Android:创建一个定期运行并执行 UI 任务的后台线程?
Android: Create a background thread that runs periodically and does UI tasks?
好的,所以我知道如何执行后台任务,我知道如何执行周期性任务(使用 handle postdelayed 和 runnable),我还知道如何从后台线程执行 UI 任务(通过处理程序),但我无法执行在 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
的错误。我明白它想说什么。但是任何人都可以建议以正确的方式做到这一点。
您可以使用异步任务。这些是为它设计的:
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
}
}
如果你想重复它,只需创建一个 runnable 来启动它,并在每次调用后安排下一个:
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);
不要忘记在您的 activity 被销毁时取消任务 :
myTask.cancel(true);
也许你更好,创建一个单独的 (Intent)Service 并使用 postDelayed 定期调用它。在您的 Activity 中创建 BroadcastReceiver 并在那里处理 UI 更改。
处理来自其他线程的 UI 更改的另一个提示:这是不可能的。因此你需要调用 runOnUiThread。 Here is how to use it
如果活动经常切换,为什么不颠倒职责。您可以创建一个执行周期性网络任务的服务。
那么,
- 要么你的活动定期调用这个服务来获取价值。
- 或者您使用侦听器系统:您创建一个接口,您的活动必须实现该接口才能收到任务完成通知
好的,所以我知道如何执行后台任务,我知道如何执行周期性任务(使用 handle postdelayed 和 runnable),我还知道如何从后台线程执行 UI 任务(通过处理程序),但我无法执行在 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
的错误。我明白它想说什么。但是任何人都可以建议以正确的方式做到这一点。
您可以使用异步任务。这些是为它设计的:
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
}
}
如果你想重复它,只需创建一个 runnable 来启动它,并在每次调用后安排下一个:
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);
不要忘记在您的 activity 被销毁时取消任务 :
myTask.cancel(true);
也许你更好,创建一个单独的 (Intent)Service 并使用 postDelayed 定期调用它。在您的 Activity 中创建 BroadcastReceiver 并在那里处理 UI 更改。
处理来自其他线程的 UI 更改的另一个提示:这是不可能的。因此你需要调用 runOnUiThread。 Here is how to use it
如果活动经常切换,为什么不颠倒职责。您可以创建一个执行周期性网络任务的服务。
那么, - 要么你的活动定期调用这个服务来获取价值。 - 或者您使用侦听器系统:您创建一个接口,您的活动必须实现该接口才能收到任务完成通知