AsyncTask stops after some time

时间:2017-04-24 17:16:49

标签: java android multithreading android-asynctask

I have a CustomAsyncTask class that enables infinite barcode scanner and I execute it in CustomApplication.
Unfortunately CustomAsyncTask::doInBackground stops after some time (minute or two).

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;
    }
}

I need this background task to be always on. Is there any good solution for this? I have tried IntentService, but the result was the same - after some time it stopped working.


EDIT

I have created this Service, although it block my main thread, but it should work in background right? Also If I put a breakpoint on if(!blocked) and press F9 it works fine (scanning part), but if I remove breakpoint and let it run - after few seconds it just turns off (scanner), but if I put a breakpoint again - it works again (sic!).

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();
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分: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输出。将过滤器设置为错误,您应该在那里显示崩溃。

答案 1 :(得分:0)

是的,这种类型的东西有一个优雅的解决方案。使用服务。特别是,JobScheduler api旨在处理这种东西。使用这个的原因是,如你所说,你有一个长期运行的任务,你不想要管理它死亡。此外,JobScheduler用于处理操作系统的副作用。我假设您希望您的作业运行,但允许该应用程序执行其正常的操作集。但是,作为一个注释,API在考虑诸如电池电量,使用的OS资源,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