请求后台任务在 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】:

你可以实现AsyncTaskonProgressUpdate()方法,然后在你的doInBackground()你可以调用publishProgress()你可以在onProgressUpdate()更新你的UI

【讨论】:

以上是关于请求后台任务在 Android 中多次运行的主要内容,如果未能解决你的问题,请参考以下文章

Android中使用IntentService运行后台任务

Android - 按请求顺序在后台运行任务

Android在后台运行任务时关闭屏幕

需要在android中每分钟运行一个后台任务

用于在后台运行日常任务的 Android WorkManager api

从后台任务中更新android UI