1、結(jié)論
子線程上可以添加,但最終還是拋到了主線程執(zhí)行
2、分析
- 添加
Fragment都會(huì)調(diào)用FragmentTransaction里面的方法,并最終調(diào)用commit()方法。該方法是一個(gè)抽象方法,其實(shí)現(xiàn)類是BackStackRecord,并最終調(diào)用到FragmentManagerImpl類的scheduleCommit()方法
void scheduleCommit() {
synchronized(this) {
boolean postponeReady = this.mPostponedTransactions != null && !this.mPostponedTransactions.isEmpty();
boolean pendingReady = this.mPendingActions != null && this.mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
this.mHost.getHandler().removeCallbacks(this.mExecCommit);
this.mHost.getHandler().post(this.mExecCommit); //切換host所在的線程
this.updateOnBackPressedCallbackEnabled();
}
}
}
可以看到在方法內(nèi)部使用了Handler,那是不是切換到了主線程呢?我們看一下這個(gè)handler在哪里賦值的。
- 該
Handler在FragmentManagerImpl類的attachController()方法內(nèi)賦值:
public void attachController(@NonNull FragmentHostCallback host, @NonNull FragmentContainer container, @Nullable Fragment parent) {
if (this.mHost != null) {
throw new IllegalStateException("Already attached");
} else {
this.mHost = host; //這里給host賦值
this.mContainer = container;
this.mParent = parent;
if (this.mParent != null) {
this.updateOnBackPressedCallbackEnabled();
}
if (host instanceof OnBackPressedDispatcherOwner) {
OnBackPressedDispatcherOwner dispatcherOwner = (OnBackPressedDispatcherOwner)host;
this.mOnBackPressedDispatcher = dispatcherOwner.getOnBackPressedDispatcher();
LifecycleOwner owner = parent != null ? parent : dispatcherOwner;
this.mOnBackPressedDispatcher.addCallback((LifecycleOwner)owner, this.mOnBackPressedCallback);
}
if (parent != null) {
this.mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
} else if (host instanceof ViewModelStoreOwner) {
ViewModelStore viewModelStore = ((ViewModelStoreOwner)host).getViewModelStore();
this.mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
} else {
this.mNonConfig = new FragmentManagerViewModel(false);
}
}
}
- 其調(diào)用方為
FragmentController類的attachHost方法:
public void attachHost(@Nullable Fragment parent) {
this.mHost.mFragmentManager.attachController(this.mHost, this.mHost, parent);
}
所以切換線程的Handler是在FragmentController類中的成員變量mHost賦值的。而mHost是在構(gòu)造方法中賦值的。
private FragmentController(FragmentHostCallback<?> callbacks) {
this.mHost = callbacks;
}
- 在FragmentActivity中調(diào)用了構(gòu)造方法
final FragmentController mFragments = FragmentController.createController(new FragmentActivity.HostCallbacks());
所以切換線程用到的Handler是在FragmentActivity中創(chuàng)建的
- 而
Activity是在主線程創(chuàng)建的,所以該Handler使用的是主線程的Looper,所以在子線程添加Fragment時(shí),會(huì)拋到主線程執(zhí)行
3、問題
可以在子線程顯示DialogFragment嗎?