嗨,我想知道Android如何管理内存,我无法在任何地方找到准确的答案.假设我有一个应用程序在当前活动堆栈上有5个活动(4个被停止,1个被恢复),没有连接服务.我按下HOME按钮,以便停止所有活动.我启动了一些其他内存消耗应用程序,整体设备内存开始变低.问题是
......我的申请会怎样?
更新:
在提出这个问题之前,我已经看过几次Activity生命周期,但它没有我的问题的答案.我做了一些测试,我有一些答案.DDMS中的"停止过程"是测试的线索.
我没有测试问题1的答案,但正如指南所说:
如果某个活动暂停或停止,系统可以通过要求完成活动或仅删除其进程来从内存中删除活动.
似乎可以轻轻地销毁一个或多个活动(使用onDestroy方法)而不会终止进程.回到它们时,您将获得(onCreate + bundle).
问题2答案:
是.通常系统杀死整个过程,这意味着包括活动和静态字段在内的所有数据都被销毁.这样做不是很好 - 你不会为任何暂停/停止的活动获得onDestroy或finialize().这就是在onPause方法之前调用saveInstanceState()的原因.onPause基本上是你应该保存的最后一个方法,因为在这个方法之后你永远不会看到onStop或onDestroy.系统可以扼杀破坏所有物体的过程,无论它们持有什么以及它们正在做什么.
问题3答案:
当你回到被杀的应用程序时会发生什么?
通常,当用户从主屏幕重新选择该任务时,系统会在某些情况下清除任务(从根活动上方的堆栈中删除所有活动).通常,如果用户未访问任务一段时间(例如30分钟),则完成此操作.
结论?
那将是它...希望我帮助我的essey :)
我的应用程序使用片段活动,它只处于纵向模式,无法旋转屏幕.
最初我使用的是这种commit()方法,但现在我计划不加区别地将这些更改commitAllowingStateLoss()为片段活动
如果不重新评估我使用片段的每个个案,是否有任何理由不得不加区分?
标题非常明显.我理解这个开发人员选项的作用.
我不明白的是以下几点:
我很想知道这个选项背后的原因.
有人会把我推向一些具体的,值得信赖的(最好是简明的)有关以下方面的信息:
系统重新创建组件的顺序和(如果适用)(片段,活动,活动的线程/ AsyncTasks /定时器,静态数据(何时卸载类?),其他类中的线程/ AsyncTasks /定时器,主机TabActivity,当应用程序在后台和前台时,ActivityGroup,绑定本地服务,应用程序,进程).
破坏可以在哪些点停止(返回应用程序时会遇到什么状态 - 比如"包括应用程序对象在内的所有状态都被破坏,进程处于活动状态"?
是否有可能(不修改Android)以编程方式自己导致相同类型的破坏,因此它与系统何时进行无法区分,或者是当我们自己选择释放内存时需要的单独机制(由onLowMemory触发)?
来自1)的所有场景的可靠再现步骤(junit.framework会吗?我还没有调查过)?
" 如果用户长时间离开任务,系统将清除除根活动之外的所有活动的任务.当用户再次返回任务时,只恢复根活动 ":这是否与进程/组件不同生命周期/破坏,还是与之相关?
我已阅读各种来源提供信息,通常不完整和误导,有时不正确.
我承认,我已经浏览了文档的某些部分,所以我可能错过了或误解了一些东西.
[编辑]为了避免误解:我要问的是Android破坏组件以释放内存,绕过 Activity.onDestroy.
当我将应用程序放在后台并稍后返回时,将出现以下序列之一:
[EDIT2] Bounty开始了.需要可靠的信息:活动,碎片,应用程序,绑定(可能是远程)服务,流程.
部分/完全销毁方案.见第1点.
当我的应用程序使用以下代码收集活动信息时,我收到了安装了大量应用程序的用户的邮件,但是他遇到了问题:
getPackageManager().queryIntentActivities(mAinIntent, 0)
Run Code Online (Sandbox Code Playgroud)
整个来源:https://github.com/ligi/FAST
这就是发生的事情
Caused by: java.lang.RuntimeException: Package manager has died
at android.app.ApplicationPackageManager.queryIntentActivities(ApplicationPackageManager.java:479)
at org.ligi.fast.BaseAppGatherAsyncTask.doInBackground(BaseAppGatherAsyncTask.java:34)
at org.ligi.fast.BaseAppGatherAsyncTask.doInBackground(BaseAppGatherAsyncTask.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more
Caused by: android.os.TransactionTooLargeExceptionTransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.content.pm.IPackageManager$Stub$Proxy.queryIntentActivities(IPackageManager.java:2230)
at android.app.ApplicationPackageManager.queryIntentActivities(ApplicationPackageManager.java:473)
... 9 more
Log:
0 D: Writing unhandled exception to: /data/data/org.ligi.fast/files/3.7-1364933885194.tracedroid
Run Code Online (Sandbox Code Playgroud)
似乎有一个问题,我正在对抗1mb边界,但如何离开那里?我怎么能得到所需的信息?有没有办法把数据分块?
让我们来看看下一个场景:
static在应用程序类中有一些变量,假设它是一个int i = 0;activity,并service从活动开始onCreate(),服务获得START_STICKY标志.service都是使用TimerTask将当前秒写入应用程序类中的变量.我退出活动START_STICKY标志而重启服务.现在我有问题:
谢谢,对不起我可怕的英语......
当我阅读android官方文档时,我注意到Android系统按任务管理活动,但它也使用后台堆栈来控制活动序列.所以我怀疑是android系统是否使用单个后栈来控制活动序列或者每个任务对应一个后栈?
我们知道,这样的场景在Android的默认流调用活动的各个onSaveInstanceState,onStop,onDestroy释放参考之前方法Activity的对象.
然而,似乎我有一个案例,当我的应用程序在后台,活动被杀死而没有调用那些方法,但我的应用程序本身不会被破坏.
但是我无法强制重现这一点.每当我在前台使用需要大量资源的应用程序时,整个过程都会被杀死,而不仅仅是活动.
哪种让我感到惊讶,因为我认为低资源上的'app kill'基本上只是旧的信号方式,Android系统是否会在不调用这些方法的情况下立即"杀死"(释放)一项活动?还是我在追逐鬼魂?
有谁知道如何从android.view.GLES20DisplayList释放位图.为什么它会让它们保持活力,即使你清洁,让我们说,ImageView手动?或者也许有一种方法可以禁用GLES20DisplayList,尝试在AndroidManifest中使用android:hardwareAccelerated ="false",仍然没有运气.
看起来只受4.2(1)影响
更新:看起来你无法在4.2.1上禁用硬件加速(bug?)
简单测试:
Android manifest:
application ... android:hardwareAccelerated="false"
System.out.println("isHardwareAccelerated: " + mListView.isHardwareAccelerated());
mListView.setLayerType(LAYER_TYPE_SOFTWARE, null);
System.out.println("isHardwareAccelerated: " + mListView.isHardwareAccelerated());
Run Code Online (Sandbox Code Playgroud)
结果:
12-06 17:15:27.129: I/System.out(30752): isHardwareAccelerated: true
12-06 17:15:27.129: I/System.out(30752): isHardwareAccelerated: true
Run Code Online (Sandbox Code Playgroud) 我看到不一致的文档和讨论有关Android内存不足时发生的情况以及操作系统重新声明内存的步骤.更具体地说,Android会以活动/片段或整个过程的粒度杀死吗?
例如,如果活动B在活动A前面启动(并且两个活动都是同一个应用程序/进程的一部分),活动A可以被操作系统杀死,而活动B位于前台,用户正在与活动B交互(假设:屏幕保持打开,当前应用程序保持在前台,没有发生方向更改)?
这个苏答案(在Android团队在谷歌的戴安娜Hackborn),从2011年表明,Android的杀死在流程的粒度,并不是一项活动.
在对Android开发者页面重新创建一个活动,它说:
如果系统当前已停止且未长时间使用或前台活动需要更多资源,系统也可能会破坏您的活动,因此系统必须关闭后台进程才能恢复内存.
注意歧义:"系统必须关闭后台进程 ".
在onSaveInstanceState的Android Developer页面上,它说:
例如,如果活动B在活动A前面启动,并且在某些时候活动A被杀死以回收资源,活动A将有机会通过此方法保存其用户界面的当前状态
在阅读了这些以及许多其他文档页面和在线讨论后,尚不清楚正确的答案是什么.
我也有关于片段的相同问题:由于内存不足而导致背景片段被杀死,而整个过程是否被杀死?
如果我没有弄错的话,Activity对象永远不会从内存中销毁,它们总是存在,直到进程被终止.所以调用finish()或Android操作系统来破坏你的Activity并不意味着它在内存中被破坏,而只意味着它现在处于'被破坏状态'(非官方名称).
为了演示,我确实覆盖了我的活动的finalize方法,然后从另一个活动的按钮点击事件中使用了System.gc().我看到正在调用我的活动的finalize方法.如果在进程运行时无法销毁活动对象,那么活动如何被垃圾回收?