恢复时间内存优化

时间:2013-07-07 07:35:55

标签: android android-activity android-lifecycle android-memory

我是根据一些事实写这个问题的。 例如,我们无法明确地控制垃圾收集器(GC)。因此,也无法检查GC何时从暂停的活动中获取内存。

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

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

2)gc只获取整个活动或少数空闲和空对象吗?

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

4)如果某些对象是垃圾收集的,那么在onResume中将它们检查为null是足以进一步访问它们的方法。

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

我很乐意听到每一个建议。 谢谢你的期待。 快乐的编码。

2 个答案:

答案 0 :(得分:1)

据我所知,GC运行在VM中的所有对象上,如果没有对象的引用,则会删除它。 Android Activity有点不同,它有自己的lifecycle
当Androids需要更多RAM用于其他应用程序(活动)时,则会调用您的活动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]));
        }
    }
}

答案 1 :(得分:1)

如果您的活动已经在后台工作了5或6个小时,那么几乎可以保证Android已经杀死了托管进程。当用户返回您的应用程序时,Android将为该应用程序创建一个新进程,然后重新实例化一个活动。一般情况下,在5或6个小时后,Android会放弃任何已保存的状态,只需从头开始重新启动您的应用(除非您为根活动(启动活动)明确指定了android:alwaysRetainTaskState="true"

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

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