gpt4 book ai didi

java - Android 后台任务、UI 线程和配置更改

转载 作者:行者123 更新时间:2023-12-02 05:56:20 24 4
gpt4 key购买 nike

为了解决跨配置更改保存后台任务的问题,我决定不保留 fragment ,而是执行以下操作:

  • onSaveInstanceState(Bundle savingState)中:
    • 取消任何当前正在运行的任务
    • 将他们的 ID 放入 bundle 中
  • onRestoreInstanceState(Bundle savingState)中:
    • 重新启动 ID 在 bundle 中的所有任务

由于我正在处理的任务不是特别长,因此重新启动它们不是问题,这不像我正在下载大文件或其他东西。

这是我的 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]));
}
}
}

因此,如果我调用 addTask()pendingTasks.put()pendingTasks.remove() 仅在 UI 线程上执行code> 在 UI 线程中,所以我不需要任何同步。

此时,我有一些问题:

  • Activity 生命周期方法 onSaveInstanceState()onRestoreInstanceState() 是否在 UI 线程上执行?
  • executor.shutdown() 是否立即返回?

文档说 executor.shutdown() 等待任何先前提交的任务完成。因此,从执行程序服务的角度来看,任务在执行最后一个命令(在本例中为 handler.post())后完成。因此,如果我在 onSaveInstanceState() 中有任何待处理的任务,那么在执行程序关闭后,UI 线程可能会有一些已发布的可运行对象要执行,对吗?由于我处于 onSaveInstanceState() 中,该 Activity 可能会被销毁,而在 onRestoreInstanceState() 中我将有一个新 Activity ?那么,当我在其中操纵一些旧 View 时,可运行对象会发生什么情况呢?重新创建 Activity 后,这些可运行对象会立即执行吗?如果在将可运行程序发布到 UI 线程之前,检查执行器当前是否正在关闭,并且只有在没有关闭时才执行此操作,不是更好吗?在这种情况下,我可以绝对确定在调用 executor.shutDown()executor.isShutdown() 将返回 true 或执行以下操作我必须等待任何任务完成吗?

最佳答案

  • Activity 生命周期方法 onSaveInstanceState() 和 onRestoreInstanceState() 是否在 UI 线程上执行?

    是的

  • 文档说 executor.shutdown() 等待任何先前提交的任务完成。

    没有。您在哪里看到该文档? ExecutorService.shutdown内容如下: 该方法不等待先前提交的任务完成执行。使用awaitTermination 来做到这一点

    • 那么当我在其中操作一些旧 View 时,可运行对象会发生什么情况?

    没什么好东西。他们所针对的 Activity 已经被破坏了。您应该提出一个标志并放弃task.onPostExecute(),或者保存它直到重新创建 Activity 。请注意,您无法将它们保存在 onSaveInstanceState() 中 - runnables 本身应该考虑到 Activity 是否处于 Activity 状态。

    • 重新创建 Activity 后,这些可运行对象是否会立即执行?

    不,除非你照顾好他们。重新创建 Activity 不仅应该重新启动后台任务,还应该使用 onPostExecute 重新启动可运行程序。

关于java - Android 后台任务、UI 线程和配置更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23054690/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com