dougM
dougM

Reputation: 87

doInBackground not executing

I am working on an app that will launch an AsyncTask to read magnetic card data. The main thread sleeps and every second checks to see if a boolean flag, waitForStripe, has been set to false. If so it will continue. I can see the AsyncTask doInBackground exit but it never reaches the onPostExecute. Originally I set the waitForSwipe variable in onPostExecute of the AsyncTask. I have worked around this by set the boolean at the end of doInBackground but I am puzzled with post execute method is not called.

I am including some logging where the onPostExecute is declared correctly. In this run, onPostExecute sets caMainWaitForStripe but still does not seem to execute.

10:04:45.940: D/Ca.PocessTrans(5360): CaiSerial  
10:04:45.960: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:1  
10:04:45.960: D/CaiReader(5360): requesting startSwipeCard in background.  
10:04:45.960: D/CaiReader(5360): doInBackground main thread? false  
10:04:46.000: I/System.out(5360): top of read loop 1, started: false  
10:04:46.520: I/System.out(5360): wait for swipe  
10:04:46.520: I/System.out(5360): wait for start 1  
10:04:46.520: I/System.out(5360): top of read loop 2, started: false  
10:04:46.960: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:2  
10:04:47.030: I/System.out(5360): wait for swipe  
10:04:47.030: I/System.out(5360): wait for start 2  
10:04:47.030: I/System.out(5360): top of read loop 3, started: false  
10:04:47.540: I/System.out(5360): wait for swipe  
10:04:47.540: I/System.out(5360): wait for start 3  

... here it was just waiting for me to swipe the card  

01-08 10:04:50.090: I/System.out(5360): top of read loop 9, started: false  
01-08 10:04:50.600: I/System.out(5360): wait for swipe  
01-08 10:04:50.600: I/System.out(5360): wait for start 9  
01-08 10:04:50.600: I/System.out(5360): top of read loop 10, started: false  
01-08 10:04:50.960: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:6  
01-08 10:04:51.110: I/System.out(5360): wait for swipe  
01-08 10:04:51.110: I/System.out(5360): wait for start 10  
01-08 10:04:51.110: I/System.out(5360): top of read loop 11, started: false  
01-08 10:04:51.120: I/System.out(5360): starting data  
01-08 10:04:51.130: I/System.out(5360): read 121 - bytes:121: val: 02  

... echoing the bytes read from card  

01-08 10:04:51.490: I/System.out(5360): read 121 - bytes:121: val: 6F  
01-08 10:04:51.500: I/System.out(5360): read 121 - bytes:121: val: 03  
01-08 10:04:51.510: I/System.out(5360): wait for swipe  
01-08 10:04:51.510: I/System.out(5360): top of read loop 12, started: true  
01-08 10:04:51.520: I/System.out(5360): end data  
01-08 10:04:51.520: I/System.out(5360): Exiting card reader total read 121  
01-08 10:04:51.550: I/System.out(5360): lrc ok  
01-08 10:04:51.550: I/System.out(5360): computed checksum: 6f  
01-08 10:04:51.550: I/System.out(5360): checksum ok  
01-08 10:04:51.680: D/CaiReader(5360): RS232 setting Enc Data  
01-08 10:04:51.680: D/EpayData(5360):  setEncryptedData : good swipe  

.. echoing encrypted data  

01-08 10:04:51.680: D/CaiReader(5360): leaving 'wait for stripe'  
01-08 10:04:51.960: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:7  
01-08 10:04:52.960: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:8  
01-08 10:04:53.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:9  
01-08 10:04:54.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:10  
01-08 10:04:55.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:11  
01-08 10:04:56.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:12  
01-08 10:04:57.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:13  
01-08 10:04:58.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:14  
01-08 10:04:59.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:15  
01-08 10:05:00.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:16  
01-08 10:05:01.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:17  
01-08 10:05:02.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:18  
01-08 10:05:03.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:19  
01-08 10:05:04.970: D/Ca.ProcessTrans(5360): wait for swipe, sleeping...:20  
01-08 10:05:05.970: D/Ca.PocessTrans(5360): break timeout 'wait for swipe'  
01-08 10:05:06.120: D/CaiReader(5360): Done, result: Data set  

I am thoroughly puzzled, it looks like onPostExecute is fired as the CaiReader (AsyncTask) goes out of scope, instead of after leaving wait for swipe.

Here is the asyncTask:

class CaiReader extends AsyncTask<EpayData, Long, String> {
    private final String S_TAG = "CaiReader";

    protected void onProgressUpdate(Integer... progress) {
        Log.d("Progress", "Progress");
}
@Override
protected void onPostExecute(String result) {
    Log.d(S_TAG, "Done, result: " + result);
    // caMainWaitSwipe = false;
}
// protected void onPostExecute(Long result) {
//    Log.d(S_TAG, "Done, result: " + result);
//}

/**
 * this is controlling task. It launches  card reader.
*/
@Override
protected String doInBackground(EpayData... params) {
    Log.d(S_TAG, "requesting startSwipeCard in background.");
    showThread(S_TAG, "doInBackground");
    EpayData epayData = params[0];
    byte[] scan = caiSerialReader.readCard();
    if (scan == null) {
        return "failure";
    }
    Map<String, String> rs232Map = CaiRs232Read.parseScan(scan);
    String KSN = rs232Map.get(CaiSerialReader.RS232_KSN);
    String encBlock = rs232Map.get(CaiSerialReader.RS232_ENC_BLOCK);
    Log.d(S_TAG, "RS232 setting Enc Data");
    epayData.setEncryptedData(encBlock, KSN);
    Log.d("CAPTURE", "KSN: " + KSN);
    Log.d("CAPTURE", "encBlock: " + encBlock);
    caMainWaitSwipe = false;
    Log.d(S_TAG, "leaving 'wait for stripe' ");
    String success = "set";
    return success;
}

}

The calling program:

if (readerType == ReaderType.RS232) {
                Log.d("Ca.PocessTrans", "CaiSerial");
                caMainWaitSwipe = true;
                int i = 0;
                CaiReader caiReader = (CaiReader) new CaiReader().execute(epayData);

                while (caMainWaitSwipe) {
                    i++;
                    if (i > 20) {
                        Log.d("Ca.PocessTrans", "break timeout 'wait for swipe'");
                    return DsiParser.timedOutError();
                    }
                    try {
                        Log.d("Ca.ProcessTrans", "wait for swipe,     sleeping...:" + i);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        Log.d("Ca.ProcessTrans", "process tran     interrupted exception");
                        e.printStackTrace();
                    }
                }
                Log.d("Ca.PocessTrans", "exit rs232 wait for stripe");
            }
            if (!epayData.isReadGood()) {
                return DsiParser.swipeError();
            }
        }
        Log.d("Ca.PocessTrans", "data read");
        authorizeTransaction(epayData);

Upvotes: 0

Views: 424

Answers (3)

ρяσѕρєя K
ρяσѕρєя K

Reputation: 132982

Currently your are not overriding AsyncTask onPostExecute() because you are returning String from doInBackground() but receiving result as Long so Change your code as :

class CaiReader extends AsyncTask<EpayData, Long, String> {
    private final String S_TAG = "CaiReader";

    protected void onProgressUpdate(Integer... progress) {
        Log.d("Progress", "Progress");
     }
@Override
protected void onPostExecute(String result) {  //<< chnage to String
    Log.d(S_TAG, "Done, result: " + result);
}

/**
 * this is controlling task. It launches  card reader.
*/
@Override
protected String doInBackground(EpayData... params) {

     //your code here
   return null;  //<< return string from here
}

}

Upvotes: 0

CChi
CChi

Reputation: 3134

I think there is something wrong with your onPostExecute method signature. The parameter should be of type string instead of type long. I recommend putting the @Override annotation on top of every overridden method so that the compiler can tell you what's wrong. Another thing is that you don't need a loop to check the status, you can do all this in a method and call it on onPostExecute.

Upvotes: 1

codeMagic
codeMagic

Reputation: 44571

If your main thread is sleeping then it won't be calling the Async and your onPostExecute() won't be reached. Have your doInBackground() sleep every second or however long you want or until condition is reached. Then you can return this value to your main activity, call a function, or whatever you want to do on the UI. Main thread shouldn't sleep. Alternatively, you could use a timer on the UI

Upvotes: 0

Related Questions