當 Android 想要退出應用時,我們總是希望完全退出。但是 Android 并沒有提供一個完全退出 App 的函數(shù)。
Google 上搜索了一下,方法有很多,但是基本都是只退出了當前的 Activity, 并沒有完全 finish 所有的 Activity。
利用存 Activity 棧的方式來 finish 所有這個方法目前來看是對我直接有效的,但是實際運行過程中, leakcanary 會報內存泄漏的異常,原因是我的 List 會對每一個 Activity 啟動時進行添加,而當我 finish 某個 activity 時,List 里對應的 Activity 無法被 GC,這樣導致我的內存開銷增加了。如果我對每一次 Activity 的 finish 之后再清除對應的 List 里的 Activity, 這樣我覺得會很麻煩,一點都不優(yōu)雅。下面介紹一下 SoftReference 對象。
SoftReference,即“軟引用”,由垃圾收集器根據(jù)內存需求自行清除。假設垃圾收集器在某個時間點確定對象是可以輕松訪問的。那時候,它可能會選擇原子地清除對該對象的所有軟引用,以及對任何其他可輕松訪問的對象的所有軟引用,通過一個強引用鏈可以從該對象到達該對象。在同一時間或稍后的時間,它將排入在引用隊列中注冊的新清除的軟引用。在虛擬機拋出OutOfMemoryError之前,所有對軟到達對象的軟引用都保證被清除。否則,在清除軟引用的時間或者對一組對不同對象的引用將被清除的順序沒有約束。但是,鼓勵虛擬機實現(xiàn)偏離清除最近創(chuàng)建或最近使用的軟引用。
softreference 可以在 Activity 完成生命周期并且沒有其他被引用的情況下被 GC 釋放。所以 List 存 SoftReference 可以解決問題。
繼承一個 Application 類
public class MyApp extends Application {
private List<SoftReference<Activity>> activityList = new LinkedList<>();
private static MyApp instance;
public static Context context;
@Override
public void onCreate(){
super.onCreate();
context = getApplicationContext();
LeakCanary.install(this);
}
public static MyApp getInstance() {
if(null == instance) {
instance = new MyApp();
}
return instance;
}
//添加 Activity 的軟引用到容器中
public void addActivity(SoftReference<Activity> softReference) {
activityList.add(softReference);
}
//遍歷所有Activity并finish
public void exit(){
for(int i=0;i<activityList.size();i++){
Activity activity = activityList.get(i).get();
if(activity != null){
activity.finish();
}
}
System.exit(0);
}
}
添加 Activity 的軟引用
在 BaseActivity 的 onCreate() 方法對繼承的 Activity 添加軟引用到 MyApp 的 List 里。
MyApp.getInstance().addActivity(new SoftReference<>(this));
調用 exit() 方法
當需要退出 App 時,只需調用 MyApp 的 exit() 方法即可。
MyApp.getInstance().exit();
原文地址:Android 使用 SoftReference 解決 Activity 存棧的內存泄漏問題
我的博客:時空路由器