/** * Called by Fragment.startActivityForResult() to implement its behavior. */ publicvoidstartActivityFromFragment(Fragment fragment, Intent intent, int requestCode, @Nullable Bundle options){ mStartedActivityFromFragment = true; try { if (requestCode == -1) { ActivityCompat.startActivityForResult(this, intent, -1, options); return; } checkForValidRequestCode(requestCode); int requestIndex = allocateRequestIndex(fragment); ActivityCompat.startActivityForResult( this, intent, ((requestIndex + 1) << 16) + (requestCode & 0xffff), options); } finally { mStartedActivityFromFragment = false; } }
// Allocates the next available startActivityForResult request index. privateintallocateRequestIndex(Fragment fragment){ // Sanity check that we havn't exhaused the request index space. if (mPendingFragmentActivityResults.size() >= MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS) { thrownew IllegalStateException("Too many pending Fragment activity results."); }
// Find an unallocated request index in the mPendingFragmentActivityResults map. while (mPendingFragmentActivityResults.indexOfKey(mNextCandidateRequestIndex) >= 0) { mNextCandidateRequestIndex = (mNextCandidateRequestIndex + 1) % MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS; }
/** * Checks whether the given request code is a valid code by masking it with 0xffff0000. Throws * an {@link IllegalArgumentException} if the code is not valid. */ staticvoidcheckForValidRequestCode(int requestCode){ if ((requestCode & 0xffff0000) != 0) { thrownew IllegalArgumentException("Can only use lower 16 bits for requestCode"); } }
/** * Dispatch incoming result to the correct fragment. */ @Override protectedvoidonActivityResult(int requestCode, int resultCode, Intent data){ mFragments.noteStateNotSaved(); int requestIndex = requestCode>>16; if (requestIndex != 0) { requestIndex--;
String who = mPendingFragmentActivityResults.get(requestIndex); mPendingFragmentActivityResults.remove(requestIndex); if (who == null) { Log.w(TAG, "Activity result delivered for unknown Fragment."); return; } Fragment targetFragment = mFragments.findFragmentByWho(who); if (targetFragment == null) { Log.w(TAG, "Activity result no fragment exists for who: " + who); } else { targetFragment.onActivityResult(requestCode & 0xffff, resultCode, data); } return; }