【问题标题】:AsyncTask stops after some timeAsyncTask 在一段时间后停止
【发布时间】:2017-04-24 17:16:48
【问题描述】:

我有一个启用无限条码扫描器的 CustomAsyncTask 类,我在 CustomApplication 中执行它。
不幸的是,CustomAsyncTask::doInBackground 在一段时间(一两分钟)后停止了。

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

【问题讨论】:

  • 发布您的堆栈跟踪。 AsyncTask 最多应该使用几秒钟。如果您需要无限期地运行某些东西,请使用服务和线程。如果它仍然崩溃,那么您的代码中有问题。
  • 我建议您使用 JobDispatcher 来完成这些作业。

标签: java android multithreading android-asynctask


【解决方案1】:

使用Service 而不是 AsyncTask。 AsyncTask 仅设计用于运行较短的后台任务。请记住,您在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 输出。将过滤器设置为错误,你的崩溃应该出现在那里。

【讨论】:

  • 我已经更新了答案。你能告诉我如何检查 IntentService 停止的原因吗?
【解决方案2】:

是的,对于这类事情有一个优雅的解决方案。使用服务。特别是,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

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2018-05-24
    • 2020-11-16
    • 2019-03-31
    • 2019-01-03
    相关资源
    最近更新 更多