【问题标题】:Requesting a background task to run multiple times in Android请求后台任务在 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 它的工作方式与异步任务相同,而且效果更好

标签: java android multithreading android-asynctask android-service


【解决方案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

    【讨论】:

      猜你喜欢
      • 2016-10-08
      • 2015-07-10
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多