首页 > 其他分享 >Android深入学习之Activity与Fragment之间回调函数的调用顺序

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

时间:2023-12-17 11:44:06浏览次数:25  
标签:调用 mFragment Fragment Bundle WelcomeFragment Activity Android WelcomeActivity Fr

本文使用的例子是用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()。

标签:调用,mFragment,Fragment,Bundle,WelcomeFragment,Activity,Android,WelcomeActivity,Fr
From: https://www.cnblogs.com/larissa-0464/p/17900871.html

相关文章

  • AndroidStudio设置密码可见不可见
    这里我们写一个在登录demo中常见的功能,当点击眼睛图片时,使密码可见或不可见,即形成一种保护,也防止了我们输入错误密码情况的出现,是很友好的一个功能。两张图片:睁眼:闭眼:大家记得复制粘贴到drawable.xml文件中。注意一下命名规则,推荐:see.png和nosee.png。然后,我们去写一下布局的代码:<L......
  • Android BPF 应用流量统计
    1.BPF和eBPFBPF(BerkeleyPacketFilter)最早的网络数据包捕获。eBPF(extendedBerkeleyPacketFilter)新出了一个BPF替换了之前老的BPF,但是名称有的时候也常BPF,也有叫eBPF的。功能得到加强,除了能网络数据包捕获外,也能用于trace内核函数,内核中自带的一个ftrac......
  • Zulip: Debugging Zulip-Mobile: Server + Android + IOS
    https://github.com/abaelhe/zuliphttps://github.com/abaelhe/zulip-mobileDebuggingSeeingwhattheappisdoingisanessentialpartofdevelopment.Avarietyoftoolsareavailabletohelpusdothat.Index:OfficialadvicefromReactNativeupstreamDeb......
  • Android程序员如何避免职业瓶颈,实现个人职业价值最大化?
    前言随着科技的不断发展,互联网行业日新月异,年轻一代的安卓开发者层出不穷。但对于已经步入中年的安卓开发者来说,面临的职业发展困境和竞争压力也开始逐渐显现。越来越多的程序员难以跟上时代的步伐,只会埋头写代码,缺乏大局观和长远的职业考虑。缺乏大局观的程序员许多程序员缺乏大局......
  • 限制Android程序员发展的不是年龄,而是这个.....
    前言在互联网圈有个默认的35岁定律:做互联网技术的,一旦年龄来到35岁,如果不能转到公司的管理岗位,还在基层默默地写程序,改bug,那么离被离职就不远了。同样,这两年网上大量的裁员信息层出不穷,不少大龄程序员都在这被淘汰。那么,我们今天一起来思考一下限制程序员发展的到底是什么?是年龄?为......
  • Android9.0 vold初始化及外部存储器挂载浅析
    一、概况在Android中,当SD卡U盘等外部存储器插入系统之后,系统会自动挂载。Vold就是负责挂载的,vold的全称是volumedaemon。实际上是负责完成系统的CDROM,USB大容量存储,MMC卡等扩展存储的挂载任务自动完成的守护进程。它提供的主要特点是支持这些存储外设的热插拔。Vold框架图关......
  • Android app 浮动时间APP(Android)
    前言全局说明浮动时间APP(Android)各大购物网站的服务器精确时间一、网址http://float.bertsir.com浮动时间,一个为抢购而生的APP,这个软件不是外挂,经常抢购的人应该必备的浮动时间App。免责声明:本号所涉及内容仅供安全研究与教学使用,如出现其他风险,后果自负。参......
  • android webview加载assets目录中的html
     加载目录:Stringurl="file:///android_asset/web/index.html";webView.loadUrl(url);完整代码:packagecom.example.h5application;importandroidx.appcompat.app.AppCompatActivity;importandroid.app.AlertDialog;importandroid.app.ProgressDialog;......
  • C-Kermit AND C-Kermit for Android
    C-KermitforAndroid:http://github.com/tesneddon/ckacka-C-KermitforAndroidThisarchivecontainsthesourcecodeforbu......
  • (原创)安卓快速使用简单的BottomNavigation(结合fragment)
    原创声明:本文所有图片和代码皆由本人制作和编写。目录前言目标效果第0步导入库第1步准备好一些资源fragmentdrawable图标第一小步第二小步第二步创建menu第三步创建navigation注意第四步绑定前言这篇文章是边写大作业边查资料边写的,查了很多资料,翻了很多论坛,也遇到了很多......