Activity
和Fragment
从创建到销毁经历了一系列的状态迁移, 在某些场景下, 可能需要监控Activity或者Fragment的状态变化.一般而言,通常在他们的管理者中获得其状态.
具体到Activity, 可以在Application
对象中监控其状态,Application对象可以监控其进程中所有的Activity的状态变化.因此需要实现自定义的Application,在其onCreate
方法中调用registerActivityLifecycleCallbacks
注册Activity的Activity状态回调, Application的onCreate方法早于Activity的任何状态回调, 因此可以监控Activity的所有状态变化, , 同时需要在AndroidManifest.xml
文件的application
标签中指定自定义的Application类名.自定义的Application实现如下:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
}
private final ActivityLifecycleCallbacks mActivityLifecycleCallbacks = new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@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) {
}
};
}
自定义的Activity的实现:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
当自定义的Activity的状态函数执行的时候, 需要调用父类(即Activity)的相应函数, 这里以onCreate为例, 其实现为(Activity.java):
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
if (getApplicationInfo().targetSdkVersion > O && mActivityInfo.isFixedOrientation()) {
final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
ta.recycle();
if (isTranslucentOrFloating) {
throw new IllegalStateException(
"Only fullscreen opaque activities can request orientation");
}
}
if (mLastNonConfigurationInstances != null) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
if (mActivityInfo.parentActivityName != null) {
if (mActionBar == null) {
mEnableDefaultActionBarUp = true;
} else {
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
}
}
if (savedInstanceState != null) {
mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
View.LAST_APP_AUTOFILL_ID);
if (mAutoFillResetNeeded) {
getAutofillManager().onCreate(savedInstanceState);
}
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;
}
其中调用getApplication().dispatchActivityCreated(this, savedInstanceState);
其实现为(Application.java):
/* 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);
}
}
}
即Application中会通过注册的回调函数通知Activity的状态变化.
对于Fragment
, 因为其宿主一般是Activity
, 所以通常在Activity中监控其状态.Fragment可以通过静态布局文件的方式创建,也可以通过调用FragmentManager
的相关方法动态创建. 为了保证监控到Fragment全部的状态变化,需要在Fragment创建之前注册回调函数.对于静态创建Fragment的场景, 需要在自定义Activity
的onCreate
方法中注册回调函数.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycleCallbacks, false);
setContentView(R.layout.activity_main);
}
private final FragmentManager.FragmentLifecycleCallbacks mFragmentLifecycleCallbacks
= new FragmentManager.FragmentLifecycleCallbacks () {
@Override
public void onFragmentPreAttached(FragmentManager fm, Fragment f, Context context) {
}
@Override
public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) {
}
// Some other override functions.
};
}
在自定义Activity的onCreate方法中调用setContentView
时, 会创建在布局文件中静态配置的Fragment
, 并把其状态迁移到CREATED
状态(FragmentManager
通过其moveToState
函数更新其管理的Fragment
状态,也是在该函数中,调用注册的状态回调函数), 因此注册回调函数要位于setContentView之前.
总结:
- Application中可以监控当前进程中所有Activity的状态变化.
- Activity中可以监控其管理的所有Fragment的状态变化,不能监控其他Activity管理的Fragment.