讓 Activity 自動關閉

1 篇文章 / 0 new
author
讓 Activity 自動關閉
 當App退到背景模式(Activity onStop)時, 長時間不用系統雖會自動回收, 但回收後再次啟動因不是從頭開始而是直接從當時的Activity啟動, 若該Activity沒有需要來自上層Activity傳入的參數就不成問題, 但若需要讀入傳入參數就會發生錯誤, 原因是 getIntent().getExtras() 取不到上層Activity傳入的資料,因為上層Activity也已經被系統回收了.

 要解決此一問題方式當然很多, 如將參數儲存,或是取法取得資料時自動 finish()等等, 這樣一來每個有讀入上層參數的Activity都需要處理,個人決得很麻煩, 所以就想當程式退到背景模式(onStop)時, 若經過一段時間沒有再被使用就自行將整個程式關閉, 如此就不會有上述情況發生. 但同時需要考量的就是怎樣的方式對現有程式加入此機制需更動的程式碼最少化.

 關於關閉程式, 網路上常見的有如下方式, 不過都不能關閉乾淨, 有些情況還是會殘留
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
 因此想到的就是將開啟的activity逐一finish(), 這樣算是最乾淨, 也最完整,因為每一個activity都可以正確完整的關閉及處理關閉前的相關動作. 要達成這目的也很單純, 就是紀錄開啟的 activity 然後在需要關閉時再依序逆向關閉即可. 做法如下

1. 需要一個class用來管理開啟的activity
public class ActivityPool {
    public static boolean cancelfinish = true;
    private static Thread finishThread;
    private static int finishCount;
    private static HashMap<String, Object> item = new HashMap<String, Object>();
    public static int autoFinishAdd(Activity act) {
        int inx = item.size()+1;
        item.put(String.valueOf(inx), act);
        return inx;
    }
    public static void autoFinishDel() {
        if (item.size()>0)
            item.remove(String.valueOf(item.size()));
    }
    public static void autoFinishClear() {
        item.clear();
    }
    public static void autoFinish(int level) {
        if ( level != item.size() ) return; //相等表示時,不是因新開activity而觸發
        finishCount = 0;
        cancelfinish = true;
        finishThread = new Thread(new Runnable() {
            public void run() {
                try {
                    while(cancelfinish) {
                        finishThread.sleep(100);
                        if (++finishCount > 6000) {//10min
                            cancelfinish = false;
                            for(int inx=item.size(); inx>0; inx--) {
                                Activity tar = (Activity)item.get(String.valueOf(inx));
                                tar.finish();
                            }
                        }
                    }
                } catch (InterruptedException e) { /*e.printStackTrace();*/ }
            }
        });
        finishThread.start();
    }
    public static void autoFinishCancel() {
        cancelfinish = false;
    }
    public static void autoFinishDestory() {
        cancelfinish = false;
        autoFinishDel();
    }
}

2. 建議新的 activity class方便後續app加入此自動關閉機制, 不然就必須在每個activity的oncreate,onstop,ondestory一一作登錄,啟動,註銷等動作
public class AutoActivity extends Activity {
    private int activityLevel = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityLevel = DataAdapter.autoFinishAdd(this);//登錄
    }
    @Override
    protected void onStart() {
        super.onStart();
        ActivityPool.autoFinishCancel();//取消檢查
    }
    @Override
    protected void onStop() {
        super.onStop();
        ActivityPool.autoFinish(activityLevel);啟動檢查
    }
    @Override
    protected void onDestroy() {
        ActivityPool.autoFinishDestory();//註銷
        super.onDestroy();
    }
}

有了這兩支 class 就完成90%了, 接下來只要將現有程式中凡是 extends Activity 通通改成 extends MyActivity, 內部的程式碼通通不用更動, 這樣App就具有背景模式下自動關閉功能了
Free Web Hosting