2017-04-24 6 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を試しましたが、結果は同じでした - しばらくしてから作業を停止しました。


EDIT

それは私のメインスレッドをブロックするが、私は、このサービスを作成しているが、それは、バックグラウンドの右に動作するはず?また、私はif(!blocked)にブレークポイントを置き、F9キーを押しても問題なく動作しますが、ブレークポイントを削除して実行させると数秒後には(スキャナー)は消えますが、再度ブレークポイントを置くと動作しますもう一度(ic!)。

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

AsyncTaskの代わりにServiceを使用してください。 AsyncTasksは、より短いバックグラウンドタスクで実行するように設計されています。 Serviceで実行するものはすべてメインスレッドで実行されるため、Serviceのバックグラウンドスレッドを使用する必要があります。

AsyncTaskまたはIntentServiceが停止している理由を教えてください。 IntentServiceでは、あなたのwhile(真)ループで、アプリケーションが何らかの理由でシャットダウンしない限り無期限に実行する必要があります。

編集 - あなたは、メインスレッドをブロックから、あなたのループを防ぐために、これを実行する必要があり

-

@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の出力を調べる必要があります。フィルタをErrorに設定すると、クラッシュが表示されます。

+0

私は答えを更新しました。 IntentServiceが停止した理由を確認する方法を教えてください。 –

0

はい、このタイプのものには洗練されたソリューションがあります。サービスを利用する。特に、JobScheduler APIはこの種のものを処理するためのものです。これを使用する理由は、あなたが述べたように、あなたは長時間実行されているタスクを持っており、それを管理する必要がないことです。さらに、JobSchedulerは、OSの副作用を処理するために構築されています。私はあなたの仕事を実行したいと思うが、アプリケーションが通常の操作を実行できるようにする。注記として、APIはバッテリレベル、使用されているOSリソース、Wi-Fi接続などの要素を検討する上で賢明ですが、ジョブを延期することができます。

公式ドキュメントはここhttps://developer.android.com/reference/android/app/job/JobScheduler.html

https://code.tutsplus.com/tutorials/using-the-jobscheduler-api-on-android-lollipop--cms-23562

関連する問題