gpt4 book ai didi

java - Activity 的成员范围和 Asynctask

转载 作者:搜寻专家 更新时间:2023-10-30 19:57:46 25 4
gpt4 key购买 nike

我在我的 Activity 类中初始化了一个成员变量

private String test = new String("A");

然后我用它在从 Activity 启动的匿名 AsyncTask 的 doInBackground() 方法中写入一个耗时很长的循环

new AsyncTask<Void, Void, Void>() {
@Override
protected void onPreExecute() {
}

@Override
protected void onPostExecute(Void result) {
}

@Override
protected Void doInBackground(Void... params) {

for (int j = 10; j >= 0; j--) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("DOINBACKGROUND ", test);
}

}.execute();

问题:当我在 Asynctask 仍在执行时离开 Activity,并且在 Activity 的 onDestroy() 执行之后,我在日志中看到成员变量是还活着,没有被摧毁。有人可以向我解释这怎么可能吗?

悬赏问题:成员变量仍然存在,因为即使在 onDestroy() 之后,由于 gc 条件和 gc 优先级,它还没有被垃圾化。这没关系。

但我怀疑是不是

  • 'test' 成员变量(和 Activity 的上下文)在引用 asynctask 结束它的内容之前不会被垃圾化,因此 asynctask 可以始终并且肯定地完成它的 doInBackground() 而不会崩溃(尽管有一个临时内存消耗)

或者相反

  • 无论 asynctask 是否运行,'test' 成员变量迟早会被垃圾处理,可能会导致 asysnctask 崩溃

最佳答案

不要混淆垃圾回收和 Activity 生命周期。

一旦所有从 GC 根对象追踪到它的引用都消失了,一个对象就可以被垃圾收集。

onDestroy() 是 Activity 生命周期的一部分。本质上,框架已完成 Activity ,并放弃了它可能持有的对 Activity 和相关资源的任何引用。

当你实例化一个匿名内部类时,它会得到一个对父对象的隐式引用。换句话说,匿名内部类始终是非静态内部类。此父引用是对您的 Activity 的引用。然后,您通过调用 execute() 将异步任务对象传递给执行程序,执行程序会在需要时保留异步任务引用,同时防止引用的 Activity 被垃圾收集.


Thus the asynctask in my snippet example will complete its doInBackground() always and surely without crashing due to NPE?

是的。但请考虑以下几点:

  • 使您的内部类静态,除非它们特别需要访问父对象。由于匿名内部类始终是非静态,因此使它们成为非匿名的。

  • 在具有独立生命周期的对象(例如 Activity 或 fragment )中混合异步操作很脆弱,最好避免。问题包括例如取消、将结果传递给已消失的对象,并保留对 Activity 等昂贵对象的 GC 预防引用。

关于java - Activity 的成员范围和 Asynctask,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31031628/

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