我正在开发一个应用程序,它将启动AsyncTask来读取磁卡数据。主线程休眠并且每秒检查一个布尔标志waitForStripe是否已设置为false。如果是这样,它将继续。我可以看到AsyncTask doInBackground出口,但它永远不会到达onPostExecute。最初我在AsyncTask的onPostExecute中设置了waitForSwipe变量。我已经解决了这个问题,在doInBackground的末尾设置了布尔值,但我对后执行方法的调用感到困惑。
我正在包含一些正确声明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)超出了范围,而不是在等待刷卡之后。
这是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);
答案 0 :(得分:1)
我认为你的onPostExecute方法签名有问题。参数应为string类型而不是long类型。我建议将@Override注释放在每个重写方法的顶部,以便编译器可以告诉你什么是错的。另一件事是你不需要循环来检查状态,你可以在一个方法中完成所有这些并在onPostExecute上调用它。
答案 1 :(得分:0)
如果您的主要线程处于休眠状态,则它将不会调用Async
,并且您的onPostExecute()
将无法访问。让你的doInBackground()
每秒睡一觉,或者你想要多长时间或者到达病情。然后,您可以将此值返回到主活动,调用函数或您想要对UI
执行的任何操作。主线不应该睡觉。或者,您可以在UI
答案 2 :(得分: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
}
}