2013-01-07 108 views
0

我正在開發一個應用程序,它將啓動一個AsyncTask來讀取磁卡數據。主線程休眠,每隔一秒檢查一次布爾標誌waitForStripe是否已設置爲false。如果是的話,它會繼續。我可以看到AsyncTask doInBackground退出,但它永遠不會到達onPostExecute。最初,我在AsyncTask的onPostExecute中設置了waitForSwipe變量。我已經通過在doInBackground的末尾設置布爾值來解決這個問題,但是我感到困惑的是後綴執行方法沒有被調用。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

「主線程睡覺」 ......主線程應該從來不睡覺。這是使用AsyncTask將工作卸載到單獨線程的完整點。 –

回答

0

如果你的主線程處於睡眠狀態,那麼它不會被調用Async和你onPostExecute()將不會被達到。讓你的睡眠時間每秒鐘或無論你想要多長時間,或者直到達到條件。然後,您可以將此值返回到您的主要活動,調用函數或任何您想在UI上執行的操作。主線不應該睡覺。或者,你可以在UI

+0

codeMagic,我不知道我明白這是如何工作的。我的循環與計時器是在主線程上。它正在等待onPostExecute運行,但它在主線程上運行,所以它何時執行?我想這個變量需要在doInBackground中設置。感謝您的洞察力。 – dougM

+0

你實際上並沒有使用計時器,而是讓主線程進入你不想做的睡眠。在循環內用'thread.sleep()'在'AsyncTask'中運行循環。然後,當成功返回到'onPostExecute()',並從那裏調用主要活動中的一個函數,告訴它變量已經改變,或者如果變量是一個字段變量並且asynctask是內部類那個活動。希望有助於 – codeMagic

1

上使用定時器我認爲你的onPostExecute方法簽名有問題。該參數應該是字符串類型而不是long類型。我建議在每個重寫的方法之上放置@Override註釋,以便編譯器可以告訴你什麼是錯的。另一件事是你不需要一個循環來檢查狀態,你可以在一個方法中完成所有這些,並在onPostExecute上調用它。

0

目前您沒有覆蓋AsyncTaskonPostExecute(),因爲你是從doInBackground()返回String但接受的結果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 
} 

} 
+0

謝謝你,這是絕對正確的。我只能接受一個答案,所以我最早接受了。似乎仍然存在問題。我編輯了我的代碼示例並添加了更多文本以顯示問題仍然存在。 – dougM

+0

@dougM:依靠你,我已經在我的回答中說了。謝謝,但是我已經回答你的問題了。正如你問的問題doInBackground這就是爲什麼我回答是正確的 –

相關問題