2017-04-24 116 views
0

我有一個CustomAsyncTask類,它啓用無限條形碼掃描器,並在CustomApplication中執行它。
不幸的是CustomAsyncTask::doInBackground在一段時間後(一兩分鐘)停止。AsyncTask在一段時間後停止

private class ScanAsync extends AsyncTask<Void, String, Void> 
{ 
    boolean blocked = false; 

    @Override 
    protected Void doInBackground(Void... params) 
    { 
     while(true) 
     { 
      if (!blocked) 
      { 
       String received = GlobalAccess.scan.scan(500); 

       if (received != null && !received.isEmpty()) 
       { 
        blocked = true; 
        publishProgress(received); 
       } 
      } 
      else 
      { 
       try 
       { 
        Thread.sleep(500); 
       } 
       catch (InterruptedException ex) 
       { 
        ex.printStackTrace(); 
       } 
      } 
     } 
    } 

    @Override 
    protected void onProgressUpdate(String... values) 
    { 
     super.onProgressUpdate(values); 
     //TODO: something with received value 
     blocked = false; 
    } 
} 

我需要這個後臺任務永遠在。有沒有什麼好的解決方案?我試過IntentService,但結果是一樣的 - 一段時間後它停止工作。


編輯

我創造了這個服務,雖然它擋住了我的主線程,但它應該在後臺工作的權利?另外,如果我在if(!blocked)上放置了一個斷點並按F9,它可以正常工作(掃描部分),但是如果我刪除斷點並讓它運行 - 幾秒鐘後它就會關閉(掃描儀),但如果我再次放置斷點 - 再次(原文如此!)。

public class ScanService extends Service 
{ 
    boolean blocked = false; 

    public ScanService() 
    { 
    } 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) 
    { 
     return null; 
     // TODO: Return the communication channel to the service. 
     //throw new UnsupportedOperationException("Not yet implemented"); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     while(true) 
     { 
      if (!blocked) 
      { 
       String received = GlobalAccess.scan.scan(500); 

       if (received != null && !received.isEmpty()) 
       { 
        //blocked = true; 
       } 
      } 
      else 
      { 
       try 
       { 
        Thread.sleep(500); 
       } 
       catch (InterruptedException ex) 
       { 
        ex.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+1

安置自己的堆棧跟蹤中如何使用它的一個例子。 'AsyncTask'應該最多使用幾秒鐘。如果你需要某些東西無限期地運行,那麼使用一個服務和一個線程。如果它仍然崩潰,那麼代碼中存在問題。 – Pztar

+0

我建議你爲這些工作使用JobDispatcher。 – HaroldSer

回答

1

使用Service而不是AsyncTask。 AsyncTasks只能用於較短的後臺任務。請記住,無論您在Service中運行什麼,都將在主線程中執行,因此您應該在Service中使用後臺線程。

你能說出爲什麼AsyncTask或IntentService停止嗎?使用IntentService,使用while(true)循環,它應該無限期地運行,除非應用程序由於某種原因而關閉。

編輯 -

你必須這樣做是爲了防止你的循環阻塞主線程 -

@Override 
public int onStartCommand(Intent intent, int flags, int startId) 
{ 

    Thread t = new Thread(new Runnable() { 
     @Override 
      public void run() { 
       while(true) { 
       // your code here 
      } 
     } 
    }); 
    t.start(); 
} 

我不知道爲什麼你的服務被停止。你需要看看你的Logcat輸出。將過濾器設置爲錯誤,並且您崩潰時應該顯示在那裏。

+0

我已經更新了答案。你能告訴我如何檢查爲什麼IntentService停止? –

0

是的,這種類型的東西有一個優雅的解決方案。使用服務。特別是,JobScheduler API是爲了處理這種東西。正如你所說,使用它的理由是,你有一個長期運行的任務,你不想管理它的死亡。另外,JobScheduler的構建是爲了處理操作系統的副作用。我假設你想讓你的作業運行,但允許應用程序執行其正常的操作。儘管如此,API在考慮諸如電池電量,正在使用的操作系統資源,WiFi連接等因素時很明智,因此作業可以推遲。

的官方文檔是這裏https://developer.android.com/reference/android/app/job/JobScheduler.html

可以在這裏找到 https://code.tutsplus.com/tutorials/using-the-jobscheduler-api-on-android-lollipop--cms-23562

相關問題