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