[英]Android background tasks, the UI Thread and configuration changes
為了解決跨配置更改保存后台任務的問題,我決定執行以下操作,而不是保留片段:
onSaveInstanceState(Bundle savedState)
:
onRestoreInstanceState(Bundle savedState)
:
由於我要處理的任務不是特別長,因此重新啟動它們不是問題,這不像我要下載大文件一樣。
這是我的TaskManager
樣子:
public class BackgroundTaskManager {
// Executor Service to run the tasks on
private final ExecutorService executor;
// list of current tasks
private final Map<String, BackgroundTask> pendingTasks;
// handler to execute stuff on the UI thread
private final Handler handler;
public BackgroundTaskManager(final ExecutorService executor) {
this.executor = executor;
this.pendingTasks = new HashMap<String, BackgroundTask>();
this.handler = new Handler(Looper.getMainLooper());
}
private void executeTask(final BackgroundTask task) {
// execute the background job in the background
executor.submit(new Runnable() {
@Override
public void run() {
task.doInBackground();
handler.post(new Runnable() {
@Override
public void run() {
// manipulate some views
task.onPostExecute();
// remove the task from the list of current tasks
pendingTasks.remove(task.getId());
// check if the list of current tasks is empty
}
});
}
});
}
/**
* Adds a task to the manager and executes it in the background
*
* @param task
* the task to be added
*/
public void addTask(final BackgroundTask task) {
pendingTasks.put(task.getId(), task);
executeTask(task);
}
public void onSaveInstanceState(Bundle savedInstanceState) {
// check if there are pendingTasks
if (!pendingTasks.isEmpty()) {
executor.shutdown();
savedInstanceState.putStringArray("pending tasks", pendingTasks.keySet().toArray(new String [1]));
}
}
}
因此,前提是我在UI線程中調用addTask()
,所以,僅在UI線程上執行pendingTasks.remove()
pendingTasks.put()
和pendingTasks.remove()
addTask()
,不需要任何同步。
在這一點上,我有一些問題:
onSaveInstanceState()
和onRestoreInstanceState()
? executor.shutdown()
是否立即返回? 該文檔說executor.shutdown()
等待任何先前提交的任務完成。 因此,從執行程序服務的角度來看,任務在執行完最后一條命令后就完成了,在本例中為handler.post()
。 因此,如果我處於onSaveInstanceState()
時有任何待處理的任務,則有可能在執行程序關閉后,UI線程中將有一些已發布的可運行對象可以執行,對嗎? 而且由於我處於onSaveInstanceState()
該活動可能會被破壞,而在onRestoreInstanceState()
我將有一個新的活動嗎? 那么我在其中操作一些舊視圖的可運行對象會發生什么呢? 重新創建活動后,將立即執行這些可運行對象嗎? 如果在將可運行對象發布到UI線程之前,先檢查執行器當前是否正在關閉並且僅在不關閉時才執行,這會更好嗎? 在這種情況下,我可以絕對確定在調用executor.shutDown()
之后executor.isShutdown()
將返回true
還是我必須等待任何任務完成?
UI線程上是否執行活動生命周期方法onSaveInstanceState()和onRestoreInstanceState()?
是
該文檔說executor.shutdown()等待任何先前提交的任務完成。
否。您在哪里看到該文檔? ExecutorService.shutdown讀取: This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that
。
沒什么好的。 他們處理的活動已被破壞。 您應該舉一個標志並放棄task.onPostExecute()
,或者保存它,直到重新創建活動。 請注意,您不能將它們保存在onSaveInstanceState()
-無論活動是否存在,可運行對象本身都應考慮在內。
不,直到您照顧好它們。 重新創建活動不僅應重新啟動后台任務,還應重新啟動具有onPostExecute
可運行onPostExecute
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.