在网上看到很多关于退出APP的例子,无非就是把所有的Activity放到一个list里,要退出的时候,遍历list一个个finish,或者发广播,Activity接收要退出的广播,然后finish自己。有些还提到了使用android.os.Process.killProcess(android.os.Process.myPid()) 或 System.exit(0); 来退出,经测试,其实这是不行的,当开启的Activity多了,这两个方法只会finish掉一两个activity而已。
对于android系统来说,它有自己的内存管理机制,我们只需要把对象占用的资源,能释放掉的尽量释放掉,例如finish掉activity、停止service、关闭照相机、释放MediaPlayer,至于其他什么关闭进程、回收垃圾不需要理会。对于比较流行的两种退出方式,有以下看法:
1.把所有打开的activity放到一个list里,要退出的时候遍历这个list,把activity一个个finish掉。
所有打开的activity都放到一个list中,那么这个list就持有Activity的强引用,而且这个list的生命周期一般都很长,贯穿整个应用,一般在application中定义。试想以下,当系统内存不足,当前应用处于后台,系统需要杀死最近最少使用的Activity,释放其占有的资源,但是这个lis持有该Activity的强引用,那么就会出现系统没法释放资源,先是出现内存泄露最后出现OOM,所以个人觉得这方法不合理。
当然,这是有解决办法:那就是这个list不要持有Activity的强引用,而是弱引用(当垃圾回收线程扫描到该内存块只有弱引用,无论系统内存足不足,都会把这内存块回收掉),就可以了。使用弱引用,那么list里的item会不会突然间就为空了呢?因为弱引用很容易被回收掉的。分两种情况来分析下:
1.内存足够的时候,系统是不会去回收这个activity占用的内存,那么list里对于的item就不会为空。(系统肯定是持有强引用,要不然怎么能回调生命周期方法,而我持有弱引用)
2.内存不足的时候,系统想要回收这个activity占用的内存(系统必定对持有这个activity的强引用进行了处理,要不然怎么能回收呢),那么我这边的list里只持弱引用,系统想回收就回收吧,反正系统都自动帮我把这个activity finish了。退出app时,做空判断,相应的activity就可以不用finish了。(系统不持有强引用,我持有弱引用)
很多人会问,为什么不使用软引用呢?因为android 3.0以后对于软、弱引用都是等同处理了,当垃圾回收线程扫描到该内存块只有软、弱引用时,无论系统内存足不足,都会把这内存块回收掉。具体可以参考android官方Caching Bitmaps文章关于软、弱引用的解释。在这里使用弱引用是为了更好地说明问题。
代码如下:
public class MyApplication extends Application {
private LinkedList<WeakReference<Activity>> activityList = new LinkedList<WeakReference<Activity>>();
@Override
public void onCreate() {
super.onCreate();
}
/***
* 将Activity的弱引用放入LinkedList进行管理
* @param mActivity
*/
public void addActivityToList(Activity mActivity) {
if (!activityList.contains(mActivity)) {
activityList.add(new WeakReference<Activity>(mActivity));
}
}
/***
* 退出,清空LinkedList的item
*/
public void clearActivityList() {
if (!activityList.isEmpty()) {
Iterator<WeakReference<Activity>> mIterator = activityList.iterator();
while (mIterator.hasNext()) {
WeakReference<Activity> weakActivity = mIterator.next();
if (weakActivity.get() != null) {
weakActivity.get().finish();
}
}
}
}
}
2.采用发广播的这种方式是可行的。建议使用静态广播,不建议使用动态广播,请参考http://blog.youkuaiyun.com/ben0612/article/details/46342611
广播类定义一个静态list保存所有activity的弱引用,接收到退出广播后,就把所有activity finish掉。原理跟实现方法与方案1类似。
注意:在退出app时要把静态变量重置,因为当退出以后,静态变量没有立即被销毁,应该是跟虚拟机还没有卸载类有关。当然啦,还是尽量少使用静态变量吧,有需要可以吧变量放application里面,通过get方法来获取。