简体   繁体   English

请求后台任务在Android中多次运行

[英]Requesting a background task to run multiple times in Android

I have a long running calculation that takes sensor data as arguments. 我进行了长时间的计算,以传感器数据作为参数。

After getting the calculation result, I would like to call a method to update a view. 得到计算结果后,我想调用一个方法来更新视图。

This calculation may take some time, therefore I'm unable to run it inside the Activity code as I receive sensor data because the UI thread freezes or slows down. 此计算可能需要一些时间,因此,由于UI线程冻结或变慢,因此在接收传感器数据时,无法在“活动”代码中运行该计算。

Since I want to run this calculation every time I receive new sensor data, what options Android offers me? 由于我想在每次收到新的传感器数据时都运行此计算,因此Android为我提供了哪些选择?

I've tried using AsyncTask . 我已经尝试使用AsyncTask I would start an AsyncTask to run the calculation with new sensor data, and the View's update method would get called inside its onPostExecute . 我将启动AsyncTask以使用新的传感器数据运行计算,然后在其onPostExecute内调用View的update方法。

Unfortunately this approach created issues with animation synchronization: an AsyncTask could finish after the next, and the View's update would get called with outdated information, effectively making its animations jittery. 不幸的是,这种方法在动画同步方面造成了问题:一个AsyncTask可能在下一个同步之后完成,并且View的更新将被过时的信息调用,从而有效地使其动画变得抖动。

I've also tried running the same AsyncTask with executeOnExecutor , passing a Single Thread Executor to it, but that didn't stop the animation jitter. 我还尝试过通过executeOnExecutor运行相同的AsyncTask,将单线程执行器传递给它,但这并没有阻止动画抖动。

Lastly, I've tried to run an IntentService with a ResultReceiver callback inside the MainActivity. 最后,我尝试在MainActivity内运行带有ResultReceiver回调的IntentService While I'm able to get it running, it only runs once. 虽然我可以运行它,但它只能运行一次。 Have I misunderstood what IntentServices are for? 我是否误解了IntentServices的用途? I can't seem to run it multiple times (using a method that creates an intent with extra parameters and calls startService with it). 我似乎无法多次运行它(使用一种使用额外参数创建意图并使用它调用startService )。

Summary : I have a slow method that operates on sensor data. 摘要 :我有一个处理传感器数据的慢方法。 I want to run it in background every time I get new sensor data, and use its result/response to update a View. 我想在每次获取新的传感器数据时在后台运行它,并使用其结果/响应来更新视图。

Any suggestions? 有什么建议么?

Though I am not sure what kind of animation you are using,depending upon the structure of your application and code, few of the options could be that rather than updating data in onPostExecute(),see if you can do it in callback method of animation which tells you that animation has finished,ie calculate it in asynctask but update your arraylist or whatever you use in callback method of animation . 尽管我不确定您使用的是哪种动画,具体取决于应用程序和代码的结构,但很少有其他选择,而不是在onPostExecute()中更新数据,请查看是否可以在动画的回调方法中进行操作它告诉您动画已完成,即在asynctask中计算动画,但更新您的arraylist或您在animation的回调方法中使用的内容。 Secondly if you have a general idea of how much time animation takes to finish you can apply handler with timer and try to match both operations by calling the animation with delay. 其次,如果您对动画需要多少时间有一个大致的了解,则可以应用带有计时器的处理程序,并通过延迟调用动画来尝试匹配两个操作。 Similarly you can use broadcast receiver or interface if the UI operation is across the activities. 同样,如果UI操作跨活动,则可以使用广播接收器或界面。

Your Service is here..... 您的服务在这里.....

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

您可以实现AsyncTask onProgressUpdate()方法,然后在doInBackground()中调用publishProgress()您可以在onProgressUpdate()更新UI

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM