请求后台任务在 Android 中多次运行
Posted
技术标签:
【中文标题】请求后台任务在 Android 中多次运行【英文标题】:Requesting a background task to run multiple times in Android 【发布时间】:2017-03-05 07:36:06 【问题描述】:我有一个长时间运行的计算,它将传感器数据作为参数。
得到计算结果后,我想调用一个方法来更新一个视图。
此计算可能需要一些时间,因此我无法在 Activity 代码中运行它,因为我收到传感器数据,因为 UI 线程冻结或变慢。
由于我想在每次收到新的传感器数据时运行此计算,android 为我提供了哪些选项?
我尝试过使用AsyncTask。我将启动一个 AsyncTask 以使用新的传感器数据运行计算,并且 View 的更新方法将在其 onPostExecute
中被调用。
不幸的是,这种方法在动画同步方面产生了问题:AsyncTask 可能会在下一个之后完成,并且 View 的更新将被调用 outdated 信息,从而有效地使其动画抖动。
我还尝试使用executeOnExecutor
运行相同的 AsyncTask,将单线程执行程序传递给它,但这并没有阻止动画抖动。
最后,我尝试在 MainActivity 中运行带有 ResultReceiver 回调的IntentService。虽然我能够让它运行,但它只运行一次。
我是否误解了 IntentServices 的用途?我似乎无法多次运行它(使用一种创建带有额外参数的意图并使用它调用startService
的方法)。
总结:我有一个对传感器数据进行操作的慢速方法。我想在每次获得新的传感器数据时在后台运行它,并使用它的结果/响应来更新视图。
有什么建议吗?
【问题讨论】:
使用 Rx java 它的工作方式与异步任务相同,而且效果更好 【参考方案1】:您的服务在这里.....
public class One extends Service
public static final long NOTIFY_INTERVAL = 10 * 1000;
private Handler handler = new Handler();
private Timer timer = null;
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
if (timer != null)
timer.cancel();
else
timer = new Timer();
timer.scheduleAtFixedRate(new DisplayTime(), 0, NOTIFY_INTERVAL);
class DisplayTime extends TimerTask
@Override
public void run()
handler.post(new Runnable()
@Override
public void run()
recall();
Toast.makeText(getApplicationContext(), "run", Toast.LENGTH_SHORT).show();
);
public void recall()
// Write here Async Task Method......
@Override
public void onDestroy()
super.onDestroy();
Toast.makeText(getApplicationContext(), "des", Toast.LENGTH_SHORT).show();
【讨论】:
我的 Activity 将如何与此服务通信?比如说,如果我的 Activity 获得传感器数据更新,它如何将它们发送到这个服务并得到它的响应? 嗨@volcano-secret,我设法使用ResultReceiver 与Activity 进行通信。我最终并没有完全使用你的方法(我不需要 TimerTask),但是子类化 Service 和使用 HandlerThread 对我有用。【参考方案2】:虽然我不确定您使用的是哪种动画,但取决于您的应用程序和代码的结构,除了更新 onPostExecute() 中的数据之外,还有一些选项可能是这样,看看您是否可以在回调中执行此操作动画方法告诉您动画已经完成,即在 asynctask 中计算它,但更新您的数组列表或您在动画回调方法中使用的任何内容。其次,如果您大致了解动画需要多长时间才能完成,您可以应用带有计时器的处理程序,并尝试通过延迟调用动画来匹配这两个操作。同样,如果 UI 操作跨活动,您可以使用广播接收器或接口。
【讨论】:
【参考方案3】:你可以实现AsyncTask
的onProgressUpdate()
方法,然后在你的doInBackground()
你可以调用publishProgress()
你可以在onProgressUpdate()
更新你的UI
【讨论】:
以上是关于请求后台任务在 Android 中多次运行的主要内容,如果未能解决你的问题,请参考以下文章