java - Activity 的成员范围和 Asynctask

标签 java android android-activity android-asynctask scope

我在我的 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/

相关文章:

android - Activity 不会破坏以在 android 中释放堆?

java - 如何使用 Selenium 在 <span> 中查找具有特定文本的元素

java - 使用 Java 在带有面板的网格中显示 ASCII 的最佳方法是什么?

Android 位图解码和缩放质量损失

android - 无法解析 com.android.tools.build :gradle:3. 2.1

java - 从另一个 Activity 调用一个 Activity 的方法

android - 登录用户后深层链接 Url 打开 Activity

java - 如何为 ActiveMQ 队列创建 Spring Boot 消费者?

java - 如何在 Java 中提取 X509 证书字段

java - 如何通过gridView.setOnItemClickListener()中的intent()传递ArrayList数据