- 用getActivity方法发起调用,只有父Activity的onActivityResult会调用,Fragment中的onActivityResult不会被调用
- 直接发起startActivityForResult调用,当前的Fragment的onActivityResult,和父Activity的onActivityResult都会调用
- 用getParentFragment发起调用,则只有父Activity和父Fragment的onActivityResult会被调用,当前的Fragment的onActivityResult不会被调用。
这里2和3的前提是如果父activity中重写了
onActivityResult,父Activity的onActivityResult中必须添加super.onActivityResult()
总结起来就是:从哪里发起调用,最终就会走到哪里。
源码分析
Fragment中直接调用startActivityForResult
(1)发起startActivityForResult调用
这种情况会直接调用到Fragment的startActivityForResult方法
//Fragment.class
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mHost == null) {
throw new IllegalStateException(“Fragment " + this + " not attached to Activity”);
}
mHost.onStartActivityFromFragment(this /fragment/, intent, requestCode, options);
}
上面的mHost对应的就是Fragment的父FragmentActivity,所以会调用到父FragmentActivity的startActivityFromFragment方法
//FragmentActivity.class
public void startActivityFromFragment(Fragment fragment, Intent intent,
int requestCode, @Nullable Bundle options) {
mStartedActivityFromFragment = true;
try {
//一般requestCode都不会为-1,所以不会走if里面
if (requestCode == -1) {
ActivityCompat.startActivityForResult(this, intent, -1, options);
return;
}
//这里检查requestCode是否越界了,不能超过2^16
checkForValidRequestCode(requestCode);
//根据这个requestIndex可以获取到对应Fragment的唯一标识mWho
int requestIndex = allocateRequestIndex(fragment);
//发起startActivityForResult调用,这里requestIndex和requestCode关联起来
ActivityCompat.startActivityForResult(
this, intent, ((requestIndex + 1) << 16) + (requestCode & 0xffff), options);
} finally {
mStartedActivityFromFragment = false;
}
}
每一个Fragment在内部都有一个唯一的标识字段who,在FragmentActivity中把所有调用startActivityFromFragment方法的fragment的requestCode和who通过key-value的方式保存在mPendingFragmentActivityResults变量中
private int allocateRequestIndex(Fragment fragment) {
…
int requestIndex = mNextCandidateRequestIndex;
//将requestIndex和fragment的mWho保存起来
mPendingFragmentActivityResults.put(requestIndex, fragment.mWho);
mNextCandidateRequestIndex =
(mNextCandidateRequestIndex + 1) % MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS;
return requestIndex;
}
这里allocateRequestIndex方法就把requestIndex和Fragment的mWho变量关联起来了
在上面的startActivityFromFragment方法中调用ActivityCompat的startActivityForResult方法发起启动Activity的时候又把requestIndex和requestCode关联起来了
这样后面回调onActivityResult方法时就可以根据requestCode获取对应的Fragment,以便调用Fragment的onActivityResult方法
最后看一下ActivityCompat的startActivityForResult方法
public static void startActivityForResult(@NonNull Activity activity, @NonNull Intent intent,
int requestCode, @Nullable Bundle options) {
if (Build.VERSION.SDK_INT >= 16)
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
{
activity.startActivityForResult(intent, requestCode, options);
} else {
activity.startActivityForResult(intent, requestCode);
}
}
(2)onActivityResult方法回调
通过断点调试的方法,我们会发现最先被回调的就是父Activity的onActivityResult,也就是我们的FragmentActivity的onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mFragments.noteStateNotSaved();
int requestIndex = requestCode>>16;
//requestIndex = 0就表示没有Fragment发起过startActivityForResult调用
if (requestIndex != 0) {
requestIndex–;
//根据requestIndex获取Fragment的who变量
String who = mPendingFragmentActivityResults.get(requestIndex);
mPendingFragmentActivityResults.remove(requestIndex);
if (who == null) {
Log.w(TAG, “Activity result delivered for unknown Fragment.”);
return;
}
//然后根据who变量获取目标Fragment
Fragment targetFragment = mFragments.findFragmentByWho(who);
if (targetFragment == null) {
Log.w(TAG, "Activity result no fragment exists for who: " + who);
} else {
//最后调用Fragment的onActivityResult
targetFragment.onActivityResult(requestCode & 0xffff, resultCode, data);
}
return;
}
…
super.onActivityResult(requestCode, resultCode, data);
}
从上面的方法中可以看出FragmentActivity中的onActivityResult方法中对于Fragment的startActivityForResult调用已经做了处理。
这里就有一个问题需要注意了,我们一般都会覆写父Activity中的onActivityResult方法,这个时候我们必须在onActivityResult方法加上super.onActivityResult(),否则Fragment中的onActivityResult方法就没有办法回调到了。
本文探讨了在Android Fragment中使用startActivityForResult时的不同调用方式及其回调机制。详细分析了源码,解释了如何从发起调用到回调过程中,请求码与Fragment的关联,以及为何需要在父Activity的onActivityResult中添加特定处理来确保Fragment的正确回调。
2764

被折叠的 条评论
为什么被折叠?



