2017-04-24 167 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

相关问题