【问题标题】:How to clean up app state if onDestroy is not guaranteed to be called如果不保证调用 onDestroy,如何清理应用程序状态
【发布时间】:2016-05-14 07:43:02
【问题描述】:

我刚刚注意到 Activity 的 onDestroy 在 Activity 被销毁时并不总是被调用。我读了android doc,确实是这样。我想到的一件事是,当这种强制终止发生时,我们如何确保应用程序状态是干净的?考虑一下这个愚蠢的代码:

公共类 MainActivity 扩展 AppCompatActivity {

byte[] bytes = new byte[1024 * 1024 * 100];
MyThread thread;

class MyThread extends Thread {

    Activity activity;

    @Override
    public void run() {
        activity = MainActivity.this;
        try {
            Thread.sleep(200000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startService(new Intent(this, LongRunningService.class));
    thread = new MyThread();
    thread.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    thread.activity = null;
    Log.e("Test", "onDestroy called");
}

}

如果不能保证调用 onDestroy,那么显然会有严重的内存泄漏。我们如何处理这种清理工作?

【问题讨论】:

  • onPause() 总是被称为“保存”东西的好地方。如果您使用AsyncTask 而不是Thread,则可以在onPause 期间取消AsyncTask,这也可以让您做更多事情。

标签: android


【解决方案1】:

如果您的应用程序被强制终止,则该进程已终止并回收内存。这不是内存泄漏。

然而,一般来说,这完全取决于谁保留了对事物的引用。如果您仅在活动的实例字段中保存对事物的引用,那么当活动变为未引用时,它们将变为未引用。问题解决了。

在您的代码中,如果线程不能保证退出,那么让Thread 保持活动引用确实是潜在的内存泄漏。您应该使用弱引用,或者基于应用程序上下文而不是活动上下文。

【讨论】:

  • 谢谢。假设有一个带有活动和前台服务的应用程序。是否有可能活动被杀死但服务没有被杀死?或者android只会在每个进程的基础上获得资源?而且我知道我提供的代码很愚蠢,只是一个极端的例子。更普遍的问题是如何在这些强制杀戮的情况下清理应用程序状态并持久化数据?还是我们根本不需要考虑?
  • Activity 可能被销毁(调用的是`onDestroy()` 方法)而不是服务的onDestroy() 方法。如果“杀死”是指 unix 进程被杀死,那么不,除非您指定活动和服务在不同的进程中运行(这不是默认值)。
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多