天天看點

快速讀懂 Fragment 與 Activity 的關系

文章目錄

    • FragmentActivity
    • FragmentController
    • FragmentContainer
    • FragmentHostCallback
    • FragmentManager
    • FragmentTransaction
    • 總結

FragmentActivity

繼承自

Activity

,支援 support.v4

Fragment

的使用,目前已成為 Android 預設

Activity

onCreate()

中進行關聯

FragmentController

相關。

protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);
				/*** 省略不重要源碼 ***/
        mFragments.dispatchCreate();
    }
           

onDestroy()

中進行去關聯

FragmentController

相關。

protected void onDestroy() {
        super.onDestroy();

        doReallyStop(false);

        mFragments.dispatchDestroy();
        mFragments.doLoaderDestroy();
    }
           

FragmentController

構造方法:

private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }
           

作為

FragmentActivity

的成員變量被初始化。

工廠函數

createContoller(FragmentHostCallback)

需要傳入一個

FragmentHostCallback

對象,這裡直接 new 了一個

HostCallbacks

,是前者的實作類。

在 Activity#onCreate()中被調用

attchHost

方法,該方法中實作了 FragmentManager 和 FragmentHostCallback 的關聯。

/**
     * Attaches the host to the FragmentManager for this controller. The host must be
     * attached before the FragmentManager can be used to manage Fragments.
     */
    public void attachHost(Fragment parent) {
        mHost.mFragmentManager.attachController(
                mHost, mHost /*container*/, parent);
    }
           

FragmentContainer

抽象類,用于管理布局 view。主要實作類為

FragmentHostCallback

/**
 * Callbacks to a {@link Fragment}'s container.
 */
public abstract class FragmentContainer {
    /**
     * Return the view with the given resource ID. May return {@code null} if the
     * view is not a child of this container.
     */
    @Nullable
    public abstract View onFindViewById(@IdRes int id);

    /**
     * Return {@code true} if the container holds any view.
     */
    public abstract boolean onHasView();
}
           

FragmentHostCallback

繼承自

FragmentContainer

,作為

FragmentController

的成員變量在其構造方法中被指派,主要實作類為

HostCallbacks

/**
     * Returns a {@link FragmentController}.
     */
    public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
        return new FragmentController(callbacks);
    }

    private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }
           

FragmentManager

抽象類,作為

FragmentHostCallback

的成員變量被初始化。主要實作類為

FragmentManagerImpl

attachController()

方法中與

FragmentHostCallback

FragmentContainer

進行關聯。由于 FragmentHostCallback 繼承自 FragmentContainer,其實也就是一個對象,隻是表現為不同的子類。

public void attachController(FragmentHostCallback host,
            FragmentContainer container, Fragment parent) {
        if (mHost != null) throw new IllegalStateException("Already attached");
        mHost = host;
        mContainer = container;
        mParent = parent;
    }
           

FragmentTransaction

抽象類,幫助

FragmentManager

管理 Fragment 的添加、移除、顯示、隐藏等操作。主要實作類為

BackStackRecord

這個類應該很熟悉了,在每次執行 Fragment 的相關操作時都需要通過 FragmentManager 來擷取該對象最終完成操作。例如:

val fragment = MyFragment()
                fragmentManager
                        .beginTransaction()
                        .add(rxPermissionsFragment, TAG)
                        .commitNowAllowingStateLoss()
           

這裡的

beginTransaction()

每次會重新初始化一個 FragmentTransation 對象:

public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }
           

總結

大緻的包含關系如下:

Activity(FragmentActivity) --> FragmentController --> FragmentContainer(FragmentHostCallback(HostCallbacks)) --> FragmentManager --> FragmentTransaction(BackStackRecord)