0

我正在开发一个应用程序,它将启动一个 AsyncTask 来读取磁卡数据。主线程休眠并每隔一秒检查布尔标志 waitForStripe 是否已设置为 false。如果是这样,它将继续。我可以看到 AsyncTask doInBackground 退出,但它永远不会到达 onPostExecute。最初我在 AsyncTask 的 onPostExecute 中设置了 waitForSwipe 变量。我通过在 doInBackground 末尾设置布尔值来解决这个问题,但我对没有调用 post execute 方法感到困惑。

我包括一些正确声明 onPostExecute 的日志记录。在这次运行中,onPostExecute 设置了 caMainWaitForStripe 但似乎仍然没有执行。

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  

我非常困惑,看起来 onPostExecute 在 CaiReader (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;
}

}

调用程序:

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);
4

3 回答 3

1

我认为您的 onPostExecute 方法签名有问题。参数应该是字符串类型而不是长类型。我建议将 @Override 注释放在每个被覆盖的方法之上,以便编译器可以告诉您出了什么问题。另一件事是您不需要循环来检查状态,您可以在一个方法中完成所有这些并在 onPostExecute 上调用它。

于 2013-01-07T19:05:28.263 回答
0

目前您并没有压倒一切AsyncTask onPostExecute(),因为您正在返回但String收到doInBackground()结果,Long因此将您的代码更改为:

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
}

}
于 2013-01-07T19:05:57.107 回答
0

如果您的主线程正在休眠,那么它将不会调用Async并且您onPostExecute()将无法到达。每隔一秒睡一觉,或者不管你doInBackground()想睡多久,或者直到达到这种状态。然后,您可以将此值返回给您的主要活动、调用函数或在UI. 主线程不应该休眠。或者,您可以在UI

于 2013-01-07T19:02:24.533 回答