如何监控Activity和Fragment状态变化

ActivityFragment从创建到销毁经历了一系列的状态迁移, 在某些场景下, 可能需要监控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的场景, 需要在自定义ActivityonCreate方法中注册回调函数.

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.
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值