Android深入学习之Activity与Fragment之间回调函数的调用顺序

发布时间 2023-12-17 11:43:31作者: 南风小斯

本文使用的例子是用WelcomeActivity托管WelcomeFragment。先来看Log。

1. WelcomeActivity WelcomeActivity created!
2. WelcomeActivity onCreate
  2.1. WelcomeFragment WelcomeFragment created!
  2.2. FragmentManager Commit: BackStackEntry{cc052a6}
  2.3. FragmentManager mName=null mIndex=-1 mCommitted=false
  2.4. FragmentManager Operations:
  2.5. FragmentManager Op #0: ADD WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
3. WelcomeActivity onStart
  3.1. FragmentManager Run: BackStackEntry{cc052a6}
  3.2. FragmentManager Added fragment to active set WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  3.3. FragmentManager add: WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  3.4. WelcomeFragment onCreate
  3.5. WelcomeFragment onCreateView
  3.6. WelcomeFragment onViewCreated
  3.7. WelcomeFragment onStart
4. WelcomeActivity onResume
  4.1. WelcomeFragment onResume
5. WelcomeActivity onPause
  5.1. WelcomeFragment onPause
6. WelcomeActivity onStop
  6.1. WelcomeFragment onStop
7. WelcomeActivity onSaveInstanceState
  7.1. WelcomeFragment onSaveInstanceState
  7.2. FragmentManager Saving view state for fragment WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202) with ...
  7.3. FragmentManager Saved state of WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202): null
  7.4. FragmentManager saveAllState: adding fragment (c6210532-3f32-4609-bcb4-420826d5bcf6): WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
8. WelcomeActivity onDestroy
  8.1. WelcomeFragment onDestroyView
  8.2. WelcomeFragment onDestroy
  8.3. FragmentManager Removed fragment from active set WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  8.4. FragmentManager initState called for fragment: WelcomeFragment{975f4e7} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
9. WelcomeActivity WelcomeActivity created!
10. WelcomeActivity onCreate
  10.1. WelcomeFragment WelcomeFragment created!
  10.2. FragmentManager Instantiated fragment WelcomeFragment{ccaebd3} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  10.3. FragmentManager restoreSaveState: active (c6210532-3f32-4609-bcb4-420826d5bcf6): WelcomeFragment{ccaebd3} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  10.4. FragmentManager Added fragment to active set WelcomeFragment{ccaebd3} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  10.5. FragmentManager restoreSaveState: added (c6210532-3f32-4609-bcb4-420826d5bcf6): WelcomeFragment{ccaebd3} (c6210532-3f32-4609-bcb4-420826d5bcf6 id=0x7f080202)
  10.6. WelcomeFragment onCreate
11. WelcomeActivity onStart
  11.1. WelcomeFragment onCreateView
  11.2. WelcomeFragment onViewCreated
  11.3. WelcomeFragment onStart
12. WelcomeActivity onResume
  12.1. WelcomeFragment onResume

结论就是都是Activity的回调先调用,在其回调方法执行过程中会调用相应的Fragment的回调方法。

下面是具体分析(注:上方有些FragmentManager日志删掉了)

首先是调用WelcomeActivity的构造函数,新建一个WelcomeActivity的实例,因此输出第1行Log。在此过程中,会调用到WelcomeActivity父类的构造函数。父类之一的ComponentActivity实现了SavedStateRegistryOwner接口,该接口继承自LifeccycleOwner接口,且ComponentActivity本身就实现了LifecycleOwner接口。(关于LifecycleOwner接口请见https://www.cnblogs.com/larissa-0464/p/17823798.html)。

在ComponentActivity中定义了SavedStateRegistryController变量并直接调用了create()方法进行了初始化。

在ComponentActivity的构造函数中,调用了SavedStateRegistryController.performAttach()方法。其中又调用了SavedStateRegistry.performAttach()方法。这两个performAttach()方法内的业务逻辑都是添加LifecycleObserver。

此外,在ComponentActivity构造函数中,调用了SavedStateRegistry.registerSavedStateProvider(KEY, SavedStateProvider)方法,该方法的业务逻辑就是把KEY和SavedStateProvider对象存在SavedStateRegistry.components变量中。components变量是一种字典类型。这里的KEY是ACTIVITY_RESULT_TAG="android:support:activity-result",SavedStateProvider对象则是:

getSavedStateRegistry().registerSavedStateProvider(ACTIVITY_RESULT_TAG,
                () -> {
                    Bundle outState = new Bundle();
                    mActivityResultRegistry.onSaveInstanceState(outState);
                    return outState;
                });

另外父类之一的FragmentActivity的构造函数中调用了init()方法。

private void init() {
        getSavedStateRegistry().registerSavedStateProvider(LIFECYCLE_TAG, () -> {
            markFragmentsCreated();
            mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
            return new Bundle();
        });
        // Ensure that the first OnConfigurationChangedListener
        // marks the FragmentManager's state as not saved
        addOnConfigurationChangedListener(newConfig -> mFragments.noteStateNotSaved());
        // Ensure that the first OnNewIntentListener
        // marks the FragmentManager's state as not saved
        addOnNewIntentListener(newConfig -> mFragments.noteStateNotSaved());
        addOnContextAvailableListener(context -> mFragments.attachHost(null /*parent*/));
    }

这里又调用了registerSavedStateProvider方法,KEY是LIFECYCLE_TAG=“android:support:lifecycle"。最后一句调用了addOnContextAvailableListener(Listener)方法,注册监听器。当Context变的可行时,将调用FragmentController.attachHost()方法,进而调用了FragmentManager.attachController()方法。如下方代码所示,在attachController()方法中又调用了registerSavedStateProvider()方法。KEY是SAVED_STATE_TAG="android:support:fragments",SavedStateProvider对象是调用FragmentManager.saveAllStateInternal()方法。

if (mHost instanceof SavedStateRegistryOwner && parent == null) {
            SavedStateRegistry registry =
                    ((SavedStateRegistryOwner) mHost).getSavedStateRegistry();
            registry.registerSavedStateProvider(SAVED_STATE_TAG, () -> {
                        return saveAllStateInternal();
                    }
            );

            Bundle savedInstanceState = registry
                    .consumeRestoredStateForKey(SAVED_STATE_TAG);
            if (savedInstanceState != null) {
                restoreSaveStateInternal(savedInstanceState);
            }
        }

此外,在父类之一的AppCompatActivity的构造函数中,调用了initDelegate()方法。

private void initDelegate() {
        // TODO: Directly connect AppCompatDelegate to SavedStateRegistry
        getSavedStateRegistry().registerSavedStateProvider(DELEGATE_TAG,
                new SavedStateRegistry.SavedStateProvider() {
                    @NonNull
                    @Override
                    public Bundle saveState() {
                        Bundle outState = new Bundle();
                        getDelegate().onSaveInstanceState(outState);
                        return outState;
                    }
                });
        addOnContextAvailableListener(new OnContextAvailableListener() {
            @Override
            public void onContextAvailable(@NonNull Context context) {
                final AppCompatDelegate delegate = getDelegate();
                delegate.installViewFactory();
                delegate.onCreate(getSavedStateRegistry()
                        .consumeRestoredStateForKey(DELEGATE_TAG));
            }
        });
    }

又调用了registerSavedStateProvider方法,KEY是DELEGATE_TAG="androidx:appcompat"。

WelcomeActivity实例化后,其onCreate()方法被调用(输出第2行Log),其中会依次调用其父类的onCreate()方法。在ComponentActivity.onCreate(Bundle)中,先调用了SavedStateRegistryController.performRestore(Bundle)方法。如果savedInstanceState不为null的话,那么会先Restore。

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        // Restore the Saved State first so that it is available to
        // OnContextAvailableListener instances
        mSavedStateRegistryController.performRestore(savedInstanceState);
        mContextAwareHelper.dispatchOnContextAvailable(this);
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
        if (mContentLayoutId != 0) {
            setContentView(mContentLayoutId);
        }
    }

调用完父类的onCreate()后,WelcomeActivity.onCreate()接下来通过FragmentManager托管WelcomeFragment。

        if(savedInstanceState==null){
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.welcome_container, WelcomeFragment.class,null)
                    .commit();
        }

其中beginTransaction()方法返回BackStackRecord对象。BackStackRecord类是FragmentTransaction的子类。随后调用add()方法添加Fragment。其中会调用到FragmentTransaction.createFragment()方法通过反射Fragment实例,因此输出第2.1行Log。此外还会给Fragment.mFragmentId等变量赋值,mFragmentId就是R.id.welcome_container。

在Fragment的构造函数中,调用了initLifecycle()方法。其中也初始化了SavedStateRegistryController变量。另外Fragment也实现了SavedStateRegistryOwner接口。

    private void initLifecycle() {
        mLifecycleRegistry = new LifecycleRegistry(this);
        mSavedStateRegistryController = SavedStateRegistryController.create(this);
        // The default factory depends on the SavedStateRegistry so it
        // needs to be reset when the SavedStateRegistry is reset
        mDefaultFactory = null;
        if (!mOnPreAttachedListeners.contains(mSavedStateAttachListener)) {
            registerOnPreAttachListener(mSavedStateAttachListener);
        }
    }

add()方法后是BackStackRecord.commit()方法,其内部调用了BackStackRecord.commitInternal(boolean)方法,由此输出了第2.2-2.5行Log。 

托管WelcomeFragment后调用WelcomeActivity.onStart()方法。在FragmentActivity.onStart()中,调用了FragmentController.execPendingActions()方法,该方法执行过程中会先后调用FragmentManager.execPendingActions(boolean),FragmentManager.generateOpsForPendingActions(),BackStackRecord.generateOps(),FragmentManager.removeRedundantOperationsAndExecute(),FragmentManager.executeOpsTogether(),BackStackRecord.expandOps(),FragmentStore.makeActive(),FragmentManager.executeOps(),BackStackRecord.executeOps(),FragmentManager.addFragment()等。

此过程中输出了第3.1-3.3行Log。

创建了WelcomeFragment的实例并添加到FragmentManager上后,紧跟着调用WelcomeFragment.onCreate(), onCreateView(), onViewCreated(), onStart()。

然后是WelcomeActivity.onResume(),WelcomeFragment.onResume()。

接下来旋转屏幕,依次调用WelcomeActivity.onPause(), WelcomeFragment.onPause(), WelcomeActivity.onStop(), WelcomeFragment.onStop()。 然后是WelcomeActivity.onSaveInstanceState(),执行过程中调用了ComponentActivity.onSaveInstanceState(),SavedStateRegistryController.performSave(Bundle),SavedStateRegistry.performSave(Bundle),其中把字典类型的components中存储的元素取出并依次调用SavedStateProvider.saveState()方法,将KEY和返回的Bundle对象存在Bundle类型的components中。然后再把components存在outBundle中并返回outBundle对象。这时KEY是SAVED_COMPONENTS_KEY="androidx.lifecycle.BundlableSavedStateRegistry.key"。

    fun performSave(outBundle: Bundle) {
        val components = Bundle()
        if (restoredState != null) {
            components.putAll(restoredState)
        }
        val it: Iterator<Map.Entry<String, SavedStateProvider>> =
            this.components.iteratorWithAdditions()
        while (it.hasNext()) {
            val (key, value) = it.next()
            components.putBundle(key, value.saveState())
        }
        if (!components.isEmpty) {
            outBundle.putBundle(SAVED_COMPONENTS_KEY, components)
        }
    }

 在依次调用saveState()方法时,就会调用到前面提过的FragmentManager.saveAllStateInternal()方法。

// FragmentManager
Bundle saveAllStateInternal() {
        Bundle bundle = new Bundle();
        // Make sure all pending operations have now been executed to get
        // our state update-to-date.
        forcePostponedTransactions();
        endAnimatingAwayFragments();
        execPendingActions(true);

        mStateSaved = true;
        mNonConfig.setIsStateSaved(true);

        // First save all active fragments.
        ArrayList<String> active = mFragmentStore.saveActiveFragments();
        ...
    }

方法执行过程中调用了FragmentStore.saveActiveFragments()方法。

ArrayList<String> saveActiveFragments() {
        ArrayList<String> active = new ArrayList<>(mActive.size());   // mActive.size()=1
        for (FragmentStateManager fragmentStateManager : mActive.values()) {
            if (fragmentStateManager != null) {
                Fragment f = fragmentStateManager.getFragment();

                fragmentStateManager.saveState();
                active.add(f.mWho);

                if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
                    Log.v(TAG, "Saved state of " + f + ": " + f.mSavedFragmentState);
                }
            }
        }
        return active;
    }

然后又调用了FragmentStateManager中的saveState()方法。

void saveState() {
        FragmentState fs = new FragmentState(mFragment);

        if (mFragment.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
            fs.mSavedFragmentState = saveBasicState();

            if (mFragment.mTargetWho != null) {
                if (fs.mSavedFragmentState == null) {
                    fs.mSavedFragmentState = new Bundle();
                }
                fs.mSavedFragmentState.putString(
                        TARGET_STATE_TAG,
                        mFragment.mTargetWho);
                if (mFragment.mTargetRequestCode != 0) {
                    fs.mSavedFragmentState.putInt(
                            TARGET_REQUEST_CODE_STATE_TAG,
                            mFragment.mTargetRequestCode);
                }
            }

        } else {
            fs.mSavedFragmentState = mFragment.mSavedFragmentState;
        }
        mFragmentStore.setSavedState(mFragment.mWho, fs);
    } 

又调用了saveBasicState()方法。在该方法中,如下调用了Fragment.performSaveInstanceState(Bundle)方法。因此输出了第7.1行Log。可见在WelcomeActivity.onSaveInstanceState()执行过程中调用了WelcomeFragment.onSaveInstanceState()方法。也就是说保存Fragment状态发生在保存Activity状态时。

private Bundle saveBasicState() {
        Bundle result = new Bundle();

        mFragment.performSaveInstanceState(result);
        mDispatcher.dispatchOnFragmentSaveInstanceState(mFragment, result, false);
        if (result.isEmpty()) {
            result = null;
        }

        if (mFragment.mView != null) {
            saveViewState();
        }
        if (mFragment.mSavedViewState != null) {
            if (result == null) {
                result = new Bundle();
            }
            result.putSparseParcelableArray(
                    VIEW_STATE_TAG, mFragment.mSavedViewState);
        }
        if (mFragment.mSavedViewRegistryState != null) {
            if (result == null) {
                result = new Bundle();
            }
            result.putBundle(VIEW_REGISTRY_STATE_TAG, mFragment.mSavedViewRegistryState);
        }
        if (!mFragment.mUserVisibleHint) {
            if (result == null) {
                result = new Bundle();
            }
            // Only add this if it's not the default value
            result.putBoolean(USER_VISIBLE_HINT_TAG, mFragment.mUserVisibleHint);
        }

        return result;
    }

上方代码中,继续执行会调用到saveViewState(),输出第7.2行Log。继续执行FragmentStore.saveActiveFragments()方法,输出第7.3行Log。继续执行FragmentManager.saveAllStateInternal()方法时,调用FragmentStore.saveAddedFragments()方法,输出第7.4行Log。

接下来被调用的是WelcomeActivity.onDestroy(),执行过程中调用WelcomeFragment.onDestroyView(), WelcomeFragment.onDestroy(),并输出了第8.3行Log。接着会调用Fragment.onDetach()方法,执行过程中调用FragmentStateManager.detach()方法,输出第8.4行Log,源码如下所示。

// FragmentStateManager
void detach() {
        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
            Log.d(TAG, "movefrom ATTACHED: " + mFragment);
        }
        mFragment.performDetach();
        mDispatcher.dispatchOnFragmentDetached(
                mFragment, false);
        mFragment.mState = Fragment.INITIALIZING;
        mFragment.mHost = null;
        mFragment.mParentFragment = null;
        mFragment.mFragmentManager = null;
        boolean beingRemoved = mFragment.mRemoving && !mFragment.isInBackStack();
        if (beingRemoved || mFragmentStore.getNonConfig().shouldDestroy(mFragment)) {
            if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
                Log.d(TAG, "initState called for fragment: " + mFragment);
            }
            mFragment.initState();
        }
    }

然后重新实例化一个WelcomeActivity对象,并调用WelcomeActivity.onCreate()方法。在FragmentActivity构造函数调用的init()方法中,注册了ContextAvailableListener,因此当Context变得可行后,调用了FragmentController.attachHost()方法,这会最终执行到FragmentManager.attachController()方法的如下代码:

if (mHost instanceof SavedStateRegistryOwner && parent == null) {
            SavedStateRegistry registry =
                    ((SavedStateRegistryOwner) mHost).getSavedStateRegistry();
            registry.registerSavedStateProvider(SAVED_STATE_TAG, () -> {
                        return saveAllStateInternal();
                    }
            );

            Bundle savedInstanceState = registry
                    .consumeRestoredStateForKey(SAVED_STATE_TAG);
            if (savedInstanceState != null) {
                restoreSaveStateInternal(savedInstanceState);
            }
        }

FragmentManager.restoreSaveStateInternal()方法执行时会先用从Bundle对象中取出的数据构造FragmentStateManager对象。构造函数源码如下:

    FragmentStateManager(@NonNull FragmentLifecycleCallbacksDispatcher dispatcher,
            @NonNull FragmentStore fragmentStore,
            @NonNull ClassLoader classLoader,
            @NonNull FragmentFactory fragmentFactory,
            @NonNull FragmentState fs) {
        mDispatcher = dispatcher;
        mFragmentStore = fragmentStore;
        mFragment = fs.instantiate(fragmentFactory, classLoader);
        if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
            Log.v(TAG, "Instantiated fragment " + mFragment);
        }
    }

可见,实例化了WelcomeFragment,因此输出第10.1和10.2行Log。虽然是实例化了一个新的WelcomeFragment对象,但在FragmentState.instantiate()方法中把从Bundle中取出的mFragmentId等信息赋给了新建的WelcomeFragment对象相应的变量上。所以对比2.5和10.2行Log可发现,只有WelcomeFragment对象是不同的,其他信息都是相同的。

FragmentManager.restoreSaveStateInternal()方法继续执行,输出第10.3行Log。继续执行调用FragmentStore.makeActive()方法,FragmentStore.restoreAddedFragments()方法,输出第10.4和10.5行Log。接下来就是WelcomeFragment.onCreate()。

然后就是WelcomeActivity.onStart(), WelcomeFragment.onCreateView(), WelcomeFragment.onViewCreated(), WelcomeFragment.onStart(), WelcomeActivity.onResume(), WelcomeFragment.onResume()。