2

我是根据一些事实写这个问题的。比如我们不能显式地控制垃圾收集器(GC)。所以也没有办法检查 GC 何时会从我暂停的活动中获取内存。

我正在谈论的测试用例:我在 onCreate 方法中分配了许多对象,包括 HashMaps 和 ArrayLists。其中一些用于存储位图的引用。现在用户通过按主页按钮暂停活动。比我长时间执行其他任务后忘记恢复相同的任务。现在,当我回到暂停的活动时。

问题是:1)在这种情况下,是否有机会假装或假设内存 GC 将首先获取什么?

2) gc 是仅获取整个活动还是仅获取少量空闲和空对象?

3)假设在很长一段时间后说大约 5 到 6 小时用户正在恢复活动,我怎么知道有些对象是垃圾收集的。

4) 如果某些对象被垃圾回收,那么在 onResume 中检查它们是否为 null 就足以进一步访问它们。

5)在这种情况下如何处理空指针访问。

我很想听听每一个建议。谢谢你的关注。快乐编码。

4

2 回答 2

1

据我所知,GC 会运行 VM 中的所有对象,如果没有对对象的引用,则会将其删除。Android Activity 有点不同,它有自己的生命周期
当 Androids 需要更多 RAM 用于其他应用程序(活动)时,会在您的 Activity onSaveInstanceState (Bundle outState)中调用。在这个地方你应该保存你需要的一切Bundle当用户回到你的活动时你可以恢复那些对象onRestoreInstanceState(Bundle savedInstanceState)

编辑:以我的应用程序为例:

public class Window {
    public Window(Bundle bundle) {
        maximized = bundle.getBoolean("maximized", maximized);
        displayed = bundle.getBoolean("displayed", displayed);
        minimized = bundle.getBoolean("minimized", minimized);
        resizable = bundle.getBoolean("resizable", resizable);
        orientation = bundle.getInt("orientation");
    }
    public Bundle bundle() {
        Bundle bundle = new Bundle();
        bundle.putBoolean("maximized", maximized);
        bundle.putBoolean("displayed", displayed);
        bundle.putBoolean("minimized", minimized);
        bundle.putBoolean("resizable", resizable);
        bundle.putInt("orientation", orientation);
        return bundle;
    }
}

和 MainActivity:

public class MainActivity extends Activity {
    ArrayList<Window> windows;
    [...]

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        Bundle[] windowsBundle = new Bundle[windows.size()];
        for(int i=0; i<windowsBundle.length; i++){
            windowsBundle[i] = windows.get(i).bundle();
        }
        savedInstanceState.putParcelableArray("windows", windowsBundle);
    }
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState){
        super.onRestoreInstanceState(savedInstanceState);
        Parcelable[] windowsParcels = savedInstanceState.getParcelableArray("windows");
        Bundle[] windowsBundle = (Bundle[]) Arrays.copyOf(windowsParcels, windowsParcels.length, Bundle[].class);
        windowsParcels = null;
        for(int i=0; i<windowsBundle.length; i++){
            windows.add(new Window(windowsBundle[i]));
        }
    }
}
于 2013-07-07T07:50:44.680 回答
1

如果您的活动已在后台运行了 5 或 6 个小时,则几乎可以肯定 Android 已经杀死了托管进程。当用户返回您的应用时,Android 将为该应用创建一个新进程,然后重新实例化一个活动。通常,在 5 或 6 小时后,Android 将丢弃所有保存的状态,并从头重新启动您的应用程序(除非您专门android:alwaysRetainTaskState="true"为您的根 Activity(启动 Activity)指定。

如果您在 5 或 6 小时后返回“暂停”活动,并且应用程序的进程已被杀死并重新创建,onCreate()则将再次在您的活动之前调用onResume()

GC与此无关。如果您的活动实例是活动的,GC 将不会回收它所引用的任何对象。如果您看到变量被设置为null,这是因为 Android 已经杀死了您的进程,然后又创建了一个新进程。

于 2013-07-07T09:22:19.813 回答