每次我们对Fragment的操作都需要通过FragmentTransaction,到了这里估计很多博客都已经说到了FragmentTransaction里面的几个操作方法,虽然在下也是要说的,顺便说一下Fragment管理的设计吧。

我们知道,没有FragmenActivity就没有Fragment。

那么为什么我们必须要继承自FragmentActivity呢,这就是Fragment设计上的便利了,开发者希望我们在使用Fragment的时候只需要关注对Fragment的操作,而Fragment的管理则交由FragmentActivity的FragmentManager来实现。
在FragmentAactivity这个类下面,当我们调用getSupportManager的时候

public class FragmentActivity extends BaseFragmentActivityJB implements
        ActivityCompat.OnRequestPermissionsResultCallback,
        ActivityCompatApi23.RequestPermissionsRequestCodeValidator {
    ···
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

    ···


    public FragmentManager getSupportFragmentManager() {
        return mFragments.getSupportFragmentManager();
    }
    ···
}

我们可以看到FragmentActivity里面有一个FragmentController,这个FragmentController定义了所有对Fragment的管理操作,包括我们的Activity在onCreate,onResume,onDestroy等各种生命周期或回调对Fragment的影响,都是由这个类来控制的。 

public class FragmentController {
    private final FragmentHostCallback<?> mHost;


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


    /**
     * Returns a {@link FragmentManager} for this controller.
     */
    public FragmentManager getSupportFragmentManager() {
        //获取到FragmentManager对象
        return mHost.getFragmentManagerImpl();
    }

FragmentHostCallback是一个抽象类,负责调用各种各样的回调,这样的话,当Avtivity的状态,生命周期发生改变的时候,就可以通过这个回调接口进行统一管理,在上面提到的HostCallbacks是FragmentActivity里面的一个继承FragmentHostCallback的内部类。下面我们来看看FragmentHostCallback的默认实现 。

public abstract class FragmentHostCallback<E> extends FragmentContainer {
    private final Activity mActivity;
    ···
    // 实例化FragmentManager对象,FragmentManagerImpl是继承自FragmentManager抽象类的,对FragmentManager的各种方法提供具体实现
    final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
    ···
}

FragmentManagerImpl里面的具体实现就是有关Fragment是如何运行的,各种各样的生命周期,判断Fragment的不同状态,切换状态,Transaction只是用作记录对Fragment的操作记录,最终调用commit的时候,实际上调用的还是FragmentManagerImpl的方法。

// FragmentManager 的实现类
final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
    ···
    @Override
    public FragmentTransaction beginTransaction() {
        // 每次的FragmentTransaction都是独立的
        return new BackStackRecord(this);
    }
    ···
}


// Transaction的实现类
final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {


    // 初始化的时候传入FragmentManagerImpl 的实例
    public BackStackRecord(FragmentManagerImpl manager) {
        mManager = manager;
    }


    @Override
    public int commit() {
        //返回栈id,要是不添加进栈,返回-1
        return commitInternal(false);
    }


    int commitInternal(boolean allowStateLoss) {
       // 提交以后无法再次提交
        if (mCommitted) throw new IllegalStateException("commit already called");
        if (FragmentManagerImpl.DEBUG) {
            Log.v(TAG, "Commit: " + this);
            LogWriter logw = new LogWriter(TAG);
            PrintWriter pw = new PrintWriter(logw);
            dump("  ", null, pw, null);
        }
        mCommitted = true;
        //是否要添加到回退栈
        if (mAddToBackStack) {
            // 在回退栈中分配栈ID
            mIndex = mManager.allocBackStackIndex(this);
        } else {
            mIndex = -1;
        }
        //执行这个Transaction
        mManager.enqueueAction(this, allowStateLoss);
        return mIndex;
    }


}

FragmentManagerImpl的部分实现

/**
     * 添加一个操作到待操作队列中
     *
     * @param action 添加的操作
     * @param allowStateLoss 是否允许丢失状态信息
     * @throws 如果Activity已经销毁了抛出IllegalStateException异常
     */
    public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
        if (!allowStateLoss) {
            // 检查状态是否丢失,默认的commit实现会执行这一步
            checkStateLoss();
        }
        synchronized (this) {
            if (mDestroyed || mHost == null) {
                throw new IllegalStateException("Activity has been destroyed");
            }
            if (mPendingActions == null) {
                mPendingActions = new ArrayList<>();
            }
            // 添加到待操作队列中
            mPendingActions.add(action);
            scheduleCommit();      //执行Commit操作
        }
    }


    private void scheduleCommit() {
        synchronized (this) {
            // 是否有延时的事务
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
            // 是否有待执行的事务
            boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
            if (postponeReady || pendingReady) {
                mHost.getHandler().removeCallbacks(mExecCommit);
                // 执行这个Runnable
                mHost.getHandler().post(mExecCommit);
            }
        }
    }


    //通过handler调用,在主线程运行
    public boolean execPendingActions() {
        //收集和执行延时的操作,这种延时是因为还没准备好??
        ensureExecReady(true);


        boolean didSomething = false;
       //根据事务对象生成待执行的操作,这个事务对象是FragmentTransaction的实现
        while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
            mExecutingActions = true;
            try {
               //优化执行事务,里面的处理逻辑相当复杂
                optimizeAndExecuteOps(mTmpRecords, mTmpIsPop);
            } finally {
               //清空缓存事务队列
                cleanupExec();
            }
            didSomething = true;
        }
        //判断FragmentList是否需要延时,进而调用moveToState修改Fragment的状态,根据状态来触发Fragment的不同生命周期
        doPendingDeferredStart();


        return didSomething;
    }

上面的就是我们通过getSupportFragmentManager()获取到FragmentManager,然后再开启事务,提交事务所经历的代码流程。控制Fragment的生命周期的回调,通过FragmentManager的moveToState方法

10-07 19:14