我是根据一些事实写这个问题的。 例如,我们无法明确地控制垃圾收集器(GC)。因此,也无法检查GC何时从暂停的活动中获取内存。
我正在谈论的测试案例: 我在onCreate方法中分配了许多对象,包括HashMaps和ArrayLists。 其中一些用于存储位图的引用。 现在用户通过按主页按钮暂停活动。 比我忘记在长时间执行其他任务后恢复相同的一个。 现在,当我回到暂停活动时。
问题是:1)在这种情况下,是否有机会假装或假设GC会首先获取内容?
2)gc只获取整个活动或少数空闲和空对象吗?
3)假设经过很长一段时间后大约5到6个小时用户正在恢复活动,我怎么知道有些对象是垃圾收集的。
4)如果某些对象是垃圾收集的,那么在onResume中将它们检查为null是足以进一步访问它们的方法。
5)如何在这种情况下处理空指针访问。
我很乐意听到每一个建议。 谢谢你的期待。 快乐的编码。
答案 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已经杀死了您的进程,后来又创建了一个新进程。