2015-10-09 101 views
2

好吧,所以我知道如何做一个后台任务,我知道如何做周期性的任务(使用handle postdelayed和runnable),我也知道如何从后台线程(通过处理程序)做UI任务,但我不能执行定期后台任务,在UI线程上执行一些操作。Android:创建一个定期运行并执行UI任务的后台线程?

我想执行一些后台任务,每分钟我都必须进行网络调用。通话结束后,根据输出我必须更新UI。我试图做这样的事情

private void DoTask() { 
     Thread thread = new Thread() { 
      public void run() { 
       Looper.prepare(); 
       final Handler handler = new Handler(); 
       handler.post(netRunnable); 
       Looper.loop(); 
      } 
     }; 
     thread.start(); 
} 

Runnable netRunnable = new Runnable() { 
    @Override 
    public void run() { 
     handler.getLooper().prepare(); 
     final Handler handler1 = new Handler(Looper.getMainLooper()); 
     if (do background work and check result){ 
      handler1.post(new Runnable() { 
       @Override 
       public void run() { 
        //Do UI Task 
       } 
      }); 
     } 
     handler.getLooper().loop(); 
     handler.postDelayed(netRunnable, 60000); 
    } 
} 

据我了解,有可能是我的执行一些基本的缺陷,但我不知道如何正确地做这个任务。现在它给出的错误是Only one Looper may be created per thread。我得到它想说的。但任何人都可以请建议以正确的方式做到这一点。

+0

检查此帖:http://stackoverflow.com/a/15472594/4516174 – yongsunCN

回答

1

也许你更好,创建一个单独的(Intent)Service并定期使用postDelayed进行调用。在您的活动中创建一个BroadcastReceiver并处理那里的UI更改。

处理来自其他线程的UI更改的另一个提示:这是不可能的。因此你需要调用runOnUiThread。 Here is how to use it

+0

意向服务是一个选项,但有两个原因我不想使用它。首先,我不需要在应用程序处于后台时执行任务,这是使用IntentService的主要原因。其次,我的需求是自我周期性运行的东西,我认为它可以以更简单的方式完成。无论如何感谢您的答复。 – varunkr

2

您可以使用异步任务。这是专为它:

http://developer.android.com/reference/android/os/AsyncTask.html

它可以让你在后台执行网络电话,那么当你得到的结果,UI线程

宣言执行动作

private class MyTask extends AsyncTask<Input, Void, Output> { 
protected Output doInBackground(Input... inputs) { 
     // do something on the network 
     return myOutput;// use this to transmit your result 
} 

protected void onPostExecute(Output result) { 
    // do something on UI thread with the result 
} 

}

如果你想再说一遍,只需创建一个可运行的启动它,并且每次调用后,安排下一个上E:

MyTask myTask; 
Handler handler = new Handler(); 

    Runnable myRunnable = new Runnable() { 
      @Override 
      public void run() { 
       MyTask myTask = new MyTask(); 
       myTask.execute(myArg); 
       handler.postDelayed(netRunnable, 60000); // schedule next call 
      } 
     } 

要启动它的第一次:

handler.postDelayed(myRunnable, 60000); 

或者,如果您要立即启动它:

handler.post(myRunnable); 

不要忘记何时取消任务您活动被破坏:

myTask.cancel(true); 
+0

什么如果您在asyncTask运行时旋转手机? – AlbAtNf

+0

它取决于是否触发配置更改事件。如果是这样,该活动将被销毁,并且AsyncTask需要被取消。如果没有配置更改,活动不会被破坏,所以我认为它是可以的。 –

+0

如果我看[this](http://stackoverflow.com/q/4748964/4791726),我认为这个任务不会被轻易取消。您也可能会失去对有效活动的引用。取消网络任务也可能不是最好的主意。 – AlbAtNf

0

如果活动频繁切换,为什么不扭转责任。您可能会创建一个执行周期性网络任务的服务。

然后, - 您的活动定期调用此服务以获取价值。 - 或者您使用侦听器系统:您创建一个界面,您的活动必须执行以便从任务完成中获得通知

相关问题