alwaystest / Blog

24 stars 2 forks source link

FragmentActivity requestCode 偏移 #70

Open alwaystest opened 6 years ago

alwaystest commented 6 years ago

FragmentActivity requestCode 偏移

标签(空格分隔): Android


    /**
     * Called by Fragment.startIntentSenderForResult() to implement its behavior.
     */
    public void startIntentSenderFromFragment(Fragment fragment, IntentSender intent,
            int requestCode, @Nullable Intent fillInIntent, int flagsMask, int flagsValues,
            int extraFlags, Bundle options) throws IntentSender.SendIntentException {
        mStartedIntentSenderFromFragment = true;
        try {
            if (requestCode == -1) {
                ActivityCompat.startIntentSenderForResult(this, intent, requestCode, fillInIntent,
                        flagsMask, flagsValues, extraFlags, options);
                return;
            }
            checkForValidRequestCode(requestCode);
            int requestIndex = allocateRequestIndex(fragment);
            ActivityCompat.startIntentSenderForResult(this, intent,
                    ((requestIndex + 1) << 16) + (requestCode & 0xffff), fillInIntent,
                    flagsMask, flagsValues, extraFlags, options);
        } finally {
            mStartedIntentSenderFromFragment = false;
        }
    }
    /**
     * Called by Fragment.requestPermissions() to implement its behavior.
     */
    void requestPermissionsFromFragment(Fragment fragment, String[] permissions,
            int requestCode) {
        if (requestCode == -1) {
            ActivityCompat.requestPermissions(this, permissions, requestCode);
            return;
        }
        checkForValidRequestCode(requestCode);
        try {
            mRequestedPermissionsFromFragment = true;
            int requestIndex = allocateRequestIndex(fragment);
            ActivityCompat.requestPermissions(this, permissions,
                    ((requestIndex + 1) << 16) + (requestCode & 0xffff));
        } finally {
            mRequestedPermissionsFromFragment = false;
        }
    }

在Fragment中直接调用startActivityForResultrequestPermissions最终调用的是Activity的方法,但是把requestCode做了偏移,区分Activity和Fragment,这样才能保证result能被成功传递回fragment。

allocateRequestIndex方法使用SparseArray把每次的ResquestCode和发起请求的Fragment做了绑定,保证result回调到的Fragment就是发起请求的Fragment。

requestIndes + 1然后才做偏移,是因为直接获取Index,值有可能为0,如果Index为0,Activity就会认为这个RequestCode是Activity发出的,所以要做一次偏移,保证Index必须大于0。