Android進階——藉助簡單便捷的ActivityLifecycleCallbacks實現全週期監聽Activity
引言
在開發中由於業務的需求,我們需要在Activity對應的生命週期方法中去完成對應的工作,比如說需要在Activity的onResume中註冊某個SDK或者廣播接收器、抑或是嘗試開啟Camera、判斷app 是否在後臺執行除了令人蛋疼的判斷當前runningProcess 或者runningTasks 方法等,然後在Activity的onPause()中及時登出或釋放掉,以前也許會在每個Activity對應的方法中增加對應的程式碼即可,但是從一定意義上說這程式碼是冗餘的且不優雅,從Android4.0之後添加了Application.ActivityLifecycleCallbacks介面,我們開發者就有了一種更優雅的方案。
一、Application.ActivityLifecycleCallbacksgais概述
記得我第一次知道這個介面之後,第一時間跑到官網中查詢文件,結果發現Google 又偷懶了,Summary部分竟然一句話都沒有關於它的描述,差點懷疑是否進錯了網站,ORZ,才發現其實是這個介面太簡單了背後的原理也十分簡單,本來我還以為會是觀察者模式,後面發現就是一個普通回撥。但是藉助它我可以優雅地監控Activity的生命週期——一經註冊,就會自動監聽整個APP 中所有Activity 的生命週期方法的執行(會在對應的父類Activity的方法被執行之後自動觸發)。
二、Application.ActivityLifecycleCallbacks原始碼急背後的原理簡要描述
Application.ActivityLifecycleCallbacks是Application中的一個介面,使用起來也很簡單,只需要呼叫registerActivityLifecycleCallbacks方法即可完成註冊(通常是在Application中完成的)。
public class Application extends ContextWrapper implements ComponentCallbacks2 {
private ArrayList<ComponentCallbacks> mComponentCallbacks =
new ArrayList<ComponentCallbacks>();
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
/** @hide */
public LoadedApk mLoadedApk;
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
public Application() {
super(null);
}
@CallSuper
public void onCreate() {
}
/**
* This method is for use in emulated process environments. It will
* never be called on a production Android device, where processes are
* removed by simply killing them; no user code (including this callback)
* is executed when doing so.
*/
@CallSuper
public void onTerminate() {
}
@CallSuper
public void onConfigurationChanged(Configuration newConfig) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
}
}
}
@CallSuper
public void onLowMemory() {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onLowMemory();
}
}
}
@CallSuper
public void onTrimMemory(int level) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
Object c = callbacks[i];
if (c instanceof ComponentCallbacks2) {
((ComponentCallbacks2)c).onTrimMemory(level);
}
}
}
}
/*
**註冊ActivityLifecycleCallbacks回撥
*/
public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.add(callback);
}
}
public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.remove(callback);
}
}
// ------------------ Internal API ------------------
/* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
savedInstanceState);
}
}
}
/* package */ void dispatchActivityStarted(Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity);
}
}
}
/* package */ void dispatchActivityResumed(Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity);
}
}
}
/* package */ void dispatchActivityPaused(Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity);
}
}
}
/* package */ void dispatchActivityStopped(Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity);
}
}
}
/* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity,
outState);
}
}
}
/* package */ void dispatchActivityDestroyed(Activity activity) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity);
}
}
}
...
}
然後在Activity的對應的生命週期方法的內部,通過Application來呼叫對應的dispatchActivityXxxxx方法,從而實現全生命週期的監聽
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback {
...
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
if (mLastNonConfigurationInstances != null) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
if (mActivityInfo.parentActivityName != null) {
if (mActionBar == null) {
mEnableDefaultActionBarUp = true;
} else {
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
}
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
mFragments.dispatchCreate();
getApplication().dispatchActivityCreated(this, savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
mCalled = true;
}
@CallSuper
protected void onStart() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
mCalled = true;
mFragments.doLoaderStart();
getApplication().dispatchActivityStarted(this);
}
...
}
三、ActivityLifecycleCallbacks的應用
Application.ActivityLifecycleCallbacks中對應的監聽的生命週期方法會在Activity中的生命方法呼叫父類的方法之後被觸發,由原始碼也可得知。
- 繼承Application重寫onCreate等方法
- 呼叫registerActivityLifecycleCallbacks方法註冊ActivityLifecycleCallbacks
package com.crazyview.activitylifecycle;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
/**
* Created by cmo on 2017/12/23.
*/
public class LifecycleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
init();
}
private void init() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Created"+"activity==null "
+(activity==null)+" activity.isFinishing() "+(activity.isFinishing())+" activity.isDestroyed() "+activity.isDestroyed());
}
@Override
public void onActivityStarted(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Started"+"activity==null "
+(activity==null)+" activity.isFinishing() "+(activity.isFinishing())+" activity.isDestroyed() "+activity.isDestroyed());
}
@Override
public void onActivityResumed(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was oResumed"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
}
@Override
public void onActivityPaused(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Pauseed"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
}
@Override
public void onActivityStopped(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Stoped"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.e("Lifecycle",activity.getLocalClassName()+" was SaveInstanceState"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Destroyed"+"activity==null"
+(activity==null)+" activity.isFinishing() "+(activity.isFinishing())+" activity.isDestroyed()"+activity.isDestroyed());
}
});
}
}
- 在清單中宣告Application,無需在Activity新增額外的程式碼就可以實現監控
package com.crazyview.activitylifecycle;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
public static final String LIFECYCLE = "MainActivity:Lifecycle";
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.e(LIFECYCLE, "onCreate() is Running__before super.onCreate called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(LIFECYCLE, "onCreate() is Running__after super.onCreate called");
}
@Override
protected void onRestart() {
Log.e(LIFECYCLE, "onRestart() is Running__before super's called");
super.onRestart();
Log.e(LIFECYCLE, "onRestart() is Running__after super's called");
}
@Override
protected void onStart() {
Log.e(LIFECYCLE, "onStart() is Running__before super.onStart called");
super.onStart();
Log.e(LIFECYCLE, "onStart() is Running__after super.onStart called");
}
@Override
protected void onResume() {
Log.e(LIFECYCLE, "onResume() is Running__before super.onResume called");
super.onResume();
Log.e(LIFECYCLE, "onResume() is Running__after super.onResume called");
}
@Override
protected void onPause() {
Log.e(LIFECYCLE, "onPause() is Running__before super's called");
super.onPause();
Log.e(LIFECYCLE, "onPause() is Running__after super's called");
}
@Override
protected void onStop() {
Log.e(LIFECYCLE, "onStop() is Running__before super's called");
super.onStop();
Log.e(LIFECYCLE, "onStop() is Running__after super's called");
}
@Override
protected void onDestroy() {
Log.e(LIFECYCLE, "onDestroy() is Running__before super's called");
super.onDestroy();
Log.e(LIFECYCLE, "onDestroy() is Running__after super's called");
}
public void toTask(View view) {
startActivity(new Intent(this, TaskActivity.class));
//finish();
}
}
開啟MainActivity時候的執行結果:
finish當前Activity時:
PS:一些有用的adb命令
1、通過adb 命令獲取當前執行的Activity
adb shell dumpsys activity | findstr "mFocusedActivity"
2、通過adb 使用命令列擷取對應的log並儲存到硬碟對應目錄下
adb logcat -s tag >d:log.txt
3、將log和當前時間 儲存到當前目錄下
adb logcat -v time >a.log
4、通過android.app.ActivityManager獲取topActivity
public static String getTopActivity(Context context) {
android.app.ActivityManager am = (android.app.ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
return cn.getShortClassName().toString();
}