Activitylifecyclecallbacks使用

yangxi_001發表於2016-12-20

Application通過ActivityLifecycleCallbacks使用介面提供了一套回撥方法,用於讓開發者對Activity的生命週期事件進行集中處理。 ActivityLifecycleCallbacks介面回撥可以簡化監測Activity的生命週期事件,在一個類中作統一處理。 ActivityLifecycleCallbacks使用要求API 14+ (Android 4.0+)。

使用方法

重寫Application的onCreate()方法,或在Application的無參構造方法內,呼叫Application.registerActivityLifecycleCallbacks()方法 ,並實現ActivityLifecycleCallbacks介面。

public class BaseApplication extends Application {
    public void onCreate() {
        super.onCreate();
        this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityStopped(Activity activity) {
                Log.e("====", activity+"onActivityStopped");
            }
            @Override
            public void onActivityStarted(Activity activity) {
                Log.e("====", activity+"onActivityStarted");
            }
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                Log.e("====", activity + "onActivitySaveInstanceState");
            }
            @Override
            public void onActivityResumed(Activity activity) {
                Log.e("====", activity + "onActivityResumed");
            }
            @Override
            public void onActivityPaused(Activity activity) {
                Log.e("====", activity + "onActivityPaused");
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
                Log.e("====", activity + "onActivityDestroyed");
            }
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                Log.e("====", activity + "onActivityCreated");
            }
        });
    };
}
    

為了測試,再新建兩個activity:MainActivity和SecondActivity,點選MainActivity裡面的按鈕可以跳轉到SecondActivity。 MainActivity程式碼如下:

    public class MainActivity extends ActionBarActivity {
        private Button btn = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn = (Button) findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent i = new Intent(MainActivity.this,SecondActivity.class);
                    startActivity(i);
                }
            });
            Log.e("====", "MainActivity  onCreate");
        }
        @Override
        protected void onResume() {
            super.onResume();
            Log.e("====", "MainActivity  onResume");
        }
        @Override
        protected void onPause() {
            super.onPause();
            Log.e("====", "MainActivity  onPause");
        }
        @Override
        protected void onStart() {
            super.onStart();
            Log.e("====", "MainActivity  onStart");
        }
    }
    

SecondActivity程式碼類似,不再貼出來。執行app,輸出如下

    11-25 16:45:24.043 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.MainActivity@2300e06conActivityCreated
    11-25 16:45:24.179 2829-2829/com.mxn.soul.demo E/====: MainActivity  onCreate
    11-25 16:45:24.238 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.MainActivity@2300e06conActivityStarted
    11-25 16:45:24.240 2829-2829/com.mxn.soul.demo E/====: MainActivity  onStart
    11-25 16:45:24.242 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.MainActivity@2300e06conActivityResumed
    11-25 16:45:24.242 2829-2829/com.mxn.soul.demo E/====: MainActivity  onResume
    11-25 16:45:36.768 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.MainActivity@2300e06conActivityPaused
    11-25 16:45:36.768 2829-2829/com.mxn.soul.demo E/====: MainActivity  onPause
    11-25 16:45:36.820 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.SecondActivity@13adc62aonActivityCreated
    11-25 16:45:36.856 2829-2829/com.mxn.soul.demo E/====: SecondActivity  onCreate
    11-25 16:45:36.858 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.SecondActivity@13adc62aonActivityStarted
    11-25 16:45:36.858 2829-2829/com.mxn.soul.demo E/====: SecondActivity onStart
    11-25 16:45:36.859 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.SecondActivity@13adc62aonActivityResumed
    11-25 16:45:36.859 2829-2829/com.mxn.soul.demo E/====: SecondActivity onResume
    11-25 16:45:37.321 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.MainActivity@2300e06conActivitySaveInstanceState
    11-25 16:45:37.321 2829-2829/com.mxn.soul.demo E/====: com.mxn.soul.demo.MainActivity@2300e06conActivityStopped
    

可以看到ActivityLifecycleCallbacks的回撥在activity生命週期方法之前,這是因為我的log資訊寫在super之後:

     @Override
    protected void onResume() {
        super.onResume();
         Log.e("====", "MainActivity  onResume");
    }
    

如果把log寫在super之前,那麼結果就是相反的了。

    @Override
    protected void onResume() {
        Log.e("====", "MainActivity  onResume");
        super.onResume();
    }
    

輸出如下:

    11-25 17:28:15.652 27469-27469/? E/====: MainActivity  onResume
    11-25 17:28:15.653 27469-27469/? E/====: com.mxn.soul.demo.MainActivity@2300e06conActivityResumed
    

用ActivityLifecycleCallbacks管理Activity堆疊

可以用ActivityLifecycleCallbacks和LinkedList來管理所有的Activity,可以實現完全退出一個應用。

public class BaseApplication extends Application  implements Application.ActivityLifecycleCallbacks {
    private LinkedList<ActivityInfo> mExistedActivitys = new LinkedList<>();
    private static BaseApplication mInstance;
    public static  synchronized BaseApplication getInstance() {
        return mInstance;
    }
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
         mInstance = this;
    }
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        if (null != mExistedActivitys && null != activity) {
            // 把新的 activity 新增到最前面,和系統的 activity 堆疊保持一致
            mExistedActivitys.offerFirst(new ActivityInfo(activity,ActivityInfo.STATE_CREATE));
        }
    }
    @Override
    public void onActivityStarted(Activity activity) {
    }
    @Override
    public void onActivityResumed(Activity activity) {
    }
    @Override
    public void onActivityPaused(Activity activity) {
    }
    @Override
    public void onActivityStopped(Activity activity) {
    }
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }
    @Override
    public void onActivityDestroyed(Activity activity) {
        if (null != mExistedActivitys && null != activity) {
            ActivityInfo info = findActivityInfo(activity);
            if (null != info) {
                mExistedActivitys.remove(info);
            }
        }
    }
    class ActivityInfo {
        private final static int STATE_NONE = 0;
        private final static int STATE_CREATE = 1;
        Activity mActivity;
        int mState;
        ActivityInfo() {
            mActivity = null;
            mState = STATE_NONE;
        }
        ActivityInfo(Activity activity, int state) {
            mActivity = activity;
            mState = state;
        }
    }
    public void exitAllActivity() {
        if (null != mExistedActivitys) {
            // 先暫停監聽(省得同時在2個地方操作列表)
            unregisterActivityLifecycleCallbacks( this );
            // 彈出的時候從頭開始彈,和系統的 activity 堆疊保持一致
            for (ActivityInfo info : mExistedActivitys) {
                if (null == info || null == info.mActivity) {
                    continue;
                }
                try {
                    info.mActivity.finish();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            mExistedActivitys.clear();
            // 退出完之後再新增監聽
            registerActivityLifecycleCallbacks( this );
        }
    }
    private ActivityInfo findActivityInfo(Activity activity) {
        if (null == activity || null == mExistedActivitys) {
            return null;
        }
        for (ActivityInfo info : mExistedActivitys) {
            if (null == info) {
                continue;
            }
            if (activity.equals(info.mActivity)) {
                return info;
            }
        }
        return null;
    }
}
    

結束程式時呼叫:

BaseApplication.getInstance().exitAllActivity() ;
   

但是如果應用內有多個程式,每建立一個程式就會跑一次Application的onCreate方法,每個程式記憶體都是獨立的, 所以通過這種方式無法實現將應用的Activity放在同一個LinkedList中,不能實現完全退出一個應用。

相關文章