Request API

1,308 阅读15分钟

官方建议并强推Request API

看一下大概的用法:

请求权限:

val permissionLauncher: ActivityResultLauncher<String> = registerForActivityResult(
        ActivityResultContracts.RequestPermission()) { result ->
            //TODO
        }
permissionLauncher.launch(permission)

请求权限的协议实现:

class RequestPermission : ActivityResultContract<String, Boolean>() {
        override fun createIntent(context: Context, input: String): Intent {
            return RequestMultiplePermissions.createIntent(arrayOf(input))
        }

        @Suppress("AutoBoxing")
        override fun parseResult(resultCode: Int, intent: Intent?): Boolean {
            if (intent == null || resultCode != Activity.RESULT_OK) return false
            val grantResults =
                intent.getIntArrayExtra(RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS)
            return grantResults?.any { result ->
                result == PackageManager.PERMISSION_GRANTED
            } == true
        }

        override fun getSynchronousResult(
            context: Context,
            input: String
        ): SynchronousResult<Boolean>? {
            val granted = ContextCompat.checkSelfPermission(
                context,
                input
            ) == PackageManager.PERMISSION_GRANTED
            return if (granted) {
                SynchronousResult(true)
            } else {
                // proceed with permission request
                null
            }
        }
    }

启动另一个Activity带返回值:

val resultLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        //TODO
    }
resultLauncher.launch(intent)

启动Activity的协议实现

class StartActivityForResult : ActivityResultContract<Intent, ActivityResult>() {

        companion object {
            /**
             * Key for the extra containing a [android.os.Bundle] generated from
             * [androidx.core.app.ActivityOptionsCompat.toBundle] or
             * [android.app.ActivityOptions.toBundle].
             *
             * This will override any [androidx.core.app.ActivityOptionsCompat] passed to
             * [androidx.activity.result.ActivityResultLauncher.launch]
             */
            const val EXTRA_ACTIVITY_OPTIONS_BUNDLE =
                "androidx.activity.result.contract.extra.ACTIVITY_OPTIONS_BUNDLE"
        }

        override fun createIntent(context: Context, input: Intent): Intent = input

        override fun parseResult(
            resultCode: Int,
            intent: Intent?
        ): ActivityResult = ActivityResult(resultCode, intent)
    }

关注registerForActivityResult方法(在ComponentActivity中):

    public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull ActivityResultContract<I, O> contract,
            @NonNull ActivityResultCallback<O> callback) {
        return registerForActivityResult(contract, mActivityResultRegistry, callback);
    }
    public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull final ActivityResultContract<I, O> contract,
            @NonNull final ActivityResultRegistry registry,
            @NonNull final ActivityResultCallback<O> callback) {
        return registry.register(
                "activity_rq#" + mNextLocalRequestCode.getAndIncrement(), this, contract, callback);
    }

三个参数:第一个是我们上面贴的协议,第二个是我一开始贴的代码,第三个是具体的callback实现

contract和callback等后面用到的时候再出场解释,先看ActivityResultRegistry;

@NonNull
    public final <I, O> ActivityResultLauncher<I> register(
            @NonNull final String key,
            @NonNull final LifecycleOwner lifecycleOwner,
            @NonNull final ActivityResultContract<I, O> contract,
            @NonNull final ActivityResultCallback<O> callback) {

        Lifecycle lifecycle = lifecycleOwner.getLifecycle();

        if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
            throw new IllegalStateException("LifecycleOwner " + lifecycleOwner + " is "
                    + "attempting to register while current state is "
                    + lifecycle.getCurrentState() + ". LifecycleOwners must call register before "
                    + "they are STARTED.");
        }

        final int requestCode = registerKey(key);
        LifecycleContainer lifecycleContainer = mKeyToLifecycleContainers.get(key);
        if (lifecycleContainer == null) {
            lifecycleContainer = new LifecycleContainer(lifecycle);
        }
        LifecycleEventObserver observer = new LifecycleEventObserver() {
            @Override
            public void onStateChanged(
                    @NonNull LifecycleOwner lifecycleOwner,
                    @NonNull Lifecycle.Event event) {
                if (Lifecycle.Event.ON_START.equals(event)) {
                    mKeyToCallback.put(key, new CallbackAndContract<>(callback, contract));
                    if (mParsedPendingResults.containsKey(key)) {
                        @SuppressWarnings("unchecked")
                        final O parsedPendingResult = (O) mParsedPendingResults.get(key);
                        mParsedPendingResults.remove(key);
                        callback.onActivityResult(parsedPendingResult);
                    }
                    final ActivityResult pendingResult = mPendingResults.getParcelable(key);
                    if (pendingResult != null) {
                        mPendingResults.remove(key);
                        callback.onActivityResult(contract.parseResult(
                                pendingResult.getResultCode(),
                                pendingResult.getData()));
                    }
                } else if (Lifecycle.Event.ON_STOP.equals(event)) {
                    mKeyToCallback.remove(key);
                } else if (Lifecycle.Event.ON_DESTROY.equals(event)) {
                    unregister(key);
                }
            }
        };
        lifecycleContainer.addObserver(observer);
        mKeyToLifecycleContainers.put(key, lifecycleContainer);

        return new ActivityResultLauncher<I>() {
            @Override
            public void launch(I input, @Nullable ActivityOptionsCompat options) {
                mLaunchedKeys.add(key);
                onLaunch(requestCode, contract, input, options);
            }

            @Override
            public void unregister() {
                ActivityResultRegistry.this.unregister(key);
            }

            @NonNull
            @Override
            public ActivityResultContract<I, ?> getContract() {
                return contract;
            }
        };
    }

这块代码干了什么事呢,首先拿到了Lifecycle,这个是用来监听生命周期,做一些生命周期监听解耦操作的。

接下来:

if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
    //
}

这块就是必须在生命周期STARTED之前调用注册,这是为啥呢?

WX20230511-155931@2x.png

STARTED之前就是onResume之前,也就是onCreate和onStart,这有什么深意吗?

其实这里想强调的并不是在哪个生命周期注册,而是申明要先注册再使用,不要在使用时再注册;比如点击按钮的时候再注册并启动使用,例如:

btn.setOnClickListener { v ->
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        //TODO
        
    }.launch(intent)
}

那这样做有什么危害吗?

假设我们调用跳转API跳转到系统页面,修改字体大小等会引起Activity重建的元素;重建它并不会保存Callback,那上面调用的Activity重建后并没有任何途径来反馈Callback;

而在STARTED之前去注册,他会监听生命周期ON_START,因为你在这之前定义了Callback,所以这块他可以重建后根据key和requestCode的映射直接拿Callback来用。

接着往下看:

    registerKey(key);
    private void registerKey(String key) {
        Integer existing = mKeyToRc.get(key);
        if (existing != null) {
            return;
        }
        int rc = generateRandomNumber();
        bindRcKey(rc, key);
    }
    private int generateRandomNumber() {
        int number = mRandom.nextInt((Integer.MAX_VALUE - INITIAL_REQUEST_CODE_VALUE) + 1)
                + INITIAL_REQUEST_CODE_VALUE;
        while (mRcToKey.containsKey(number)) {
            number = mRandom.nextInt((Integer.MAX_VALUE - INITIAL_REQUEST_CODE_VALUE) + 1)
                    + INITIAL_REQUEST_CODE_VALUE;
        }
        return number;
    }
    private void bindRcKey(int rc, String key) {
        mRcToKey.put(rc, key);
        mKeyToRc.put(key, rc);
    }

根据key来生成一个位于0x00010000到Integer.MAX_VALUE之间的数作为requestCode,如果生成重复了,那就在下面的while中别出来。

这里有两个容器:mRcToKey,mKeyToRc

mRcToKey用于dispatch,也就是处理阶段;根据requestCode找到对应的key,因为目前里面的代码都是根据key来映射的;

mKeyToRc用于onLaunch之前,主要是根据key来提供requestCode;

接着往下走:

LifecycleContainer lifecycleContainer = mKeyToLifecycleContainers.get(key);
        if (lifecycleContainer == null) {
            lifecycleContainer = new LifecycleContainer(lifecycle);
        }
    private static class LifecycleContainer {
        final Lifecycle mLifecycle;
        private final ArrayList<LifecycleEventObserver> mObservers;

        LifecycleContainer(@NonNull Lifecycle lifecycle) {
            mLifecycle = lifecycle;
            mObservers = new ArrayList<>();
        }

        void addObserver(@NonNull LifecycleEventObserver observer) {
            mLifecycle.addObserver(observer);
            mObservers.add(observer);
        }

        void clearObservers() {
            for (LifecycleEventObserver observer: mObservers) {
                mLifecycle.removeObserver(observer);
            }
            mObservers.clear();
        }
    }

这块就是个小单元块,把Lifecycle和它将要定于的Observer封装到一块去;

往下看:

        LifecycleEventObserver observer = new LifecycleEventObserver() {
            @Override
            public void onStateChanged(
                    @NonNull LifecycleOwner lifecycleOwner,
                    @NonNull Lifecycle.Event event) {
                if (Lifecycle.Event.ON_START.equals(event)) {
                    mKeyToCallback.put(key, new CallbackAndContract<>(callback, contract));
                    if (mParsedPendingResults.containsKey(key)) {
                        @SuppressWarnings("unchecked")
                        final O parsedPendingResult = (O) mParsedPendingResults.get(key);
                        mParsedPendingResults.remove(key);
                        callback.onActivityResult(parsedPendingResult);
                    }
                    final ActivityResult pendingResult = mPendingResults.getParcelable(key);
                    if (pendingResult != null) {
                        mPendingResults.remove(key);
                        callback.onActivityResult(contract.parseResult(
                                pendingResult.getResultCode(),
                                pendingResult.getData()));
                    }
                } else if (Lifecycle.Event.ON_STOP.equals(event)) {
                    mKeyToCallback.remove(key);
                } else if (Lifecycle.Event.ON_DESTROY.equals(event)) {
                    unregister(key);
                }
            }
        };
        lifecycleContainer.addObserver(observer);
        mKeyToLifecycleContainers.put(key, lifecycleContainer);

这块就是定义了一个LifecycleEventObserver,和Lifecycle关联起来,在对应的实现中去监听生命周期变化来处理对应的业务。

onStateChanged中监听了三个生命周期:

ON_START:以key映射协议和Callback;如果存在重建后需要执行的业务则直接执行,这就是前面说的为啥要在STARTED生命周期之前注册。

ON_STOP:对Callback做移除,这里再强调一遍,重建不缓存Callback;这里可能部分人会有点疑问,我从A跳到B,这里走了onStop,我还会回来的呀,这里移除了,还怎么调用callback;举个例子:A跳到B,A到了onStop,于是移除了callback;当A从B返回时,会走onReStart-onStart,重走这些生命周期;又因为A跳转后并没有到onDestroy,所以callback等数据并没有被销毁;于是这里在onStart中重新去绑定。【抬头看看ON_START中的操作】

ON_DESTROY:Activity销毁或者重建,在这里做解注册;

    @MainThread
    final void unregister(@NonNull String key) {
        if (!mLaunchedKeys.contains(key)) {
            // Only remove the key -> requestCode mapping if there isn't a launch in flight
            Integer rc = mKeyToRc.remove(key);
            if (rc != null) {
                mRcToKey.remove(rc);
            }
        }
        mKeyToCallback.remove(key);
        if (mParsedPendingResults.containsKey(key)) {
            Log.w(LOG_TAG, "Dropping pending result for request " + key + ": "
                    + mParsedPendingResults.get(key));
            mParsedPendingResults.remove(key);
        }
        if (mPendingResults.containsKey(key)) {
            Log.w(LOG_TAG, "Dropping pending result for request " + key + ": "
                    + mPendingResults.<ActivityResult>getParcelable(key));
            mPendingResults.remove(key);
        }
        LifecycleContainer lifecycleContainer = mKeyToLifecycleContainers.get(key);
        if (lifecycleContainer != null) {
            lifecycleContainer.clearObservers();
            mKeyToLifecycleContainers.remove(key);
        }
    }

来看看解注册都做了啥?

mLaunchedKeys是只要调用了launch就加入进去,等到dispatch的时候就会remove;在这里就是如果那些还没执行launch的api完全可以移除,因为重建还会再次添加进来;里面的key是一个双向移除;

callback也肯定得移除;

mParsedPendingResults和mPendingResults是对立存在的两个容器;mParsedPendingResults是用来对不需要启动Activity就能获取结果的数据(例如申请权限)做Activity重建存储的,那mPendingResults就是需要启动Activity时防止Activity重建用来做存储的容器。

生命周期容器也是释放对应的监听;

在这里是解注册,可能也会有人有疑惑,这块都释放了,重建后去哪整数据呢?这个也不要担心,因为在这之前已经做了数据存储,就是onSaveInstanceState,它是肯定在ON_DESTROY之前执行的。

有存必有取,onRestoreInstanceState;

等会再来说存取;先继续看代码;

        return new ActivityResultLauncher<I>() {
            @Override
            public void launch(I input, @Nullable ActivityOptionsCompat options) {
                mLaunchedKeys.add(key);
                Integer innerCode = mKeyToRc.get(key);
                onLaunch((innerCode != null) ? innerCode : requestCode, contract, input, options);
            }

            @Override
            public void unregister() {
                ActivityResultRegistry.this.unregister(key);
            }

            @NonNull
            @Override
            public ActivityResultContract<I, ?> getContract() {
                return contract;
            }
        };

register最终返回了一个ActivityResultLauncher,它里面有三个方法;

第一个方法就是前面说的,当执行launch的时候mLaunchedKeys会记录下来这个正在执行的key;后面onLaunch是具体的执行; unregister对应的实现前面已经看过了,getContract是原样返回;

这里着重看一下onLaunch;这个onLaunch是这个类里面的抽象类,具体的实现方法在哪呢?

因为我们是在ConponentActivity中调用的registerForActivityResult,也是在里面初始化的ActivityResultRegistry,我们看看具体的实现:

private final ActivityResultRegistry mActivityResultRegistry = new ActivityResultRegistry() {

        @Override
        public <I, O> void onLaunch(
                final int requestCode,
                @NonNull ActivityResultContract<I, O> contract,
                I input,
                @Nullable ActivityOptionsCompat options) {
            ComponentActivity activity = ComponentActivity.this;

            // Immediate result path
            final ActivityResultContract.SynchronousResult<O> synchronousResult =
                    contract.getSynchronousResult(activity, input);
            if (synchronousResult != null) {
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        dispatchResult(requestCode, synchronousResult.getValue());
                    }
                });
                return;
            }

            // Start activity path
            Intent intent = contract.createIntent(activity, input);
            Bundle optionsBundle = null;
            // If there are any extras, we should defensively set the classLoader
            if (intent.getExtras() != null && intent.getExtras().getClassLoader() == null) {
                intent.setExtrasClassLoader(activity.getClassLoader());
            }
            if (intent.hasExtra(EXTRA_ACTIVITY_OPTIONS_BUNDLE)) {
                optionsBundle = intent.getBundleExtra(EXTRA_ACTIVITY_OPTIONS_BUNDLE);
                intent.removeExtra(EXTRA_ACTIVITY_OPTIONS_BUNDLE);
            } else if (options != null) {
                optionsBundle = options.toBundle();
            }
            if (ACTION_REQUEST_PERMISSIONS.equals(intent.getAction())) {

                // requestPermissions path
                String[] permissions = intent.getStringArrayExtra(EXTRA_PERMISSIONS);

                if (permissions == null) {
                    permissions = new String[0];
                }

                ActivityCompat.requestPermissions(activity, permissions, requestCode);
            } else if (ACTION_INTENT_SENDER_REQUEST.equals(intent.getAction())) {
                IntentSenderRequest request =
                        intent.getParcelableExtra(EXTRA_INTENT_SENDER_REQUEST);
                try {
                    // startIntentSenderForResult path
                    ActivityCompat.startIntentSenderForResult(activity, request.getIntentSender(),
                            requestCode, request.getFillInIntent(), request.getFlagsMask(),
                            request.getFlagsValues(), 0, optionsBundle);
                } catch (final IntentSender.SendIntentException e) {
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            dispatchResult(requestCode, RESULT_CANCELED,
                                    new Intent().setAction(ACTION_INTENT_SENDER_REQUEST)
                                            .putExtra(EXTRA_SEND_INTENT_EXCEPTION, e));
                        }
                    });
                }
            } else {
                // startActivityForResult path
                ActivityCompat.startActivityForResult(activity, intent, requestCode, optionsBundle);
            }
        }
    };

首先是synchronousResult,这是个啥?其实这个我们前面见过,就是权限协议那块的实现,再看一眼

    class RequestPermission : ActivityResultContract<String, Boolean>() {
        override fun createIntent(context: Context, input: String): Intent {
            return RequestMultiplePermissions.createIntent(arrayOf(input))
        }

        @Suppress("AutoBoxing")
        override fun parseResult(resultCode: Int, intent: Intent?): Boolean {
            if (intent == null || resultCode != Activity.RESULT_OK) return false
            val grantResults =
                intent.getIntArrayExtra(RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS)
            return grantResults?.any { result ->
                result == PackageManager.PERMISSION_GRANTED
            } == true
        }

        //注释1
        override fun getSynchronousResult(
            context: Context,
            input: String
        ): SynchronousResult<Boolean>? {
            val granted = ContextCompat.checkSelfPermission(
                context,
                input
            ) == PackageManager.PERMISSION_GRANTED
            return if (granted) {
                SynchronousResult(true)
            } else {
                // proceed with permission request
                null
            }
        }
    }

最后一个方法(//注释1)就是,这个方法的作用主要就是用来区分是否需要启动另一个Activity,如果不需要直接在这个方法去做处理;像权限这边就是如果申请的权限已经授予了则不需要往下执行申请了,直接通过dispatchResult来下发处理结果;

    @MainThread
    public final <O> boolean dispatchResult(int requestCode,
            @SuppressLint("UnknownNullness") O result) {
        String key = mRcToKey.get(requestCode);
        if (key == null) {
            return false;
        }

        CallbackAndContract<?> callbackAndContract = mKeyToCallback.get(key);
        if (callbackAndContract == null || callbackAndContract.mCallback == null) {
            // Remove any pending result
            mPendingResults.remove(key);
            // And add these pre-parsed pending results in their place
            mParsedPendingResults.put(key, result);
        } else {
            @SuppressWarnings("unchecked")
            ActivityResultCallback<O> callback =
                    (ActivityResultCallback<O>) callbackAndContract.mCallback;
            if (mLaunchedKeys.remove(key)) {
                callback.onActivityResult(result);
            }
        }
        return true;
    }

根据requestCode拿到对应的key,然后执行下发;callback还在的情况下就直接下发执行,不在的话则通过mPendingResults缓存起来等重新ON_START的时候再执行;

callback目前看到是在ON_STOP会被移除,Activity重建也会被移除,然后在生命周期ON_START中重新绑定;

继续onLaunch代码往下看

Intent intent = contract.createIntent(activity, input);

这个就是之前协议中的实现方法,在这里做了获取;

            Bundle optionsBundle = null;
            // If there are any extras, we should defensively set the classLoader
            if (intent.getExtras() != null && intent.getExtras().getClassLoader() == null) {
                intent.setExtrasClassLoader(activity.getClassLoader());
            }
            if (intent.hasExtra(EXTRA_ACTIVITY_OPTIONS_BUNDLE)) {
                optionsBundle = intent.getBundleExtra(EXTRA_ACTIVITY_OPTIONS_BUNDLE);
                intent.removeExtra(EXTRA_ACTIVITY_OPTIONS_BUNDLE);
            } else if (options != null) {
                optionsBundle = options.toBundle();
            }

这块不做过多解释;

            if (ACTION_REQUEST_PERMISSIONS.equals(intent.getAction())) {

                // requestPermissions path
                String[] permissions = intent.getStringArrayExtra(EXTRA_PERMISSIONS);

                if (permissions == null) {
                    permissions = new String[0];
                }

                ActivityCompat.requestPermissions(activity, permissions, requestCode);
            }

判断Action是否为申请权限,这个Action是哪来的?看看之前的权限协议

    class RequestPermission : ActivityResultContract<String, Boolean>() {
        override fun createIntent(context: Context, input: String): Intent {
            return RequestMultiplePermissions.createIntent(arrayOf(input))
        }
        //省略....
    }
internal fun createIntent(input: Array<String>): Intent {
    return Intent(ACTION_REQUEST_PERMISSIONS).putExtra(EXTRA_PERMISSIONS, input)
}

这里就是那个Action;

 else if (ACTION_INTENT_SENDER_REQUEST.equals(intent.getAction())) {
                IntentSenderRequest request =
                        intent.getParcelableExtra(EXTRA_INTENT_SENDER_REQUEST);
                try {
                    // startIntentSenderForResult path
                    ActivityCompat.startIntentSenderForResult(activity, request.getIntentSender(),
                            requestCode, request.getFillInIntent(), request.getFlagsMask(),
                            request.getFlagsValues(), 0, optionsBundle);
                } catch (final IntentSender.SendIntentException e) {
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            dispatchResult(requestCode, RESULT_CANCELED,
                                    new Intent().setAction(ACTION_INTENT_SENDER_REQUEST)
                                            .putExtra(EXTRA_SEND_INTENT_EXCEPTION, e));
                        }
                    });
                }
            } 

这里是Google支付的;

else {
    // startActivityForResult path
    ActivityCompat.startActivityForResult(activity, intent, requestCode, optionsBundle);
    }

这个是默认兜底跳转,Activity跳转;跳转之后,处理完业务,回来得走回调;

    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (!mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

这里可以看到根据mActivityResultRegistry.dispatchResult的返回值(目前是true)来拦击了这个业务的返回值,在dispatchResult中进行业务下发;

    public final boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {
        String key = mRcToKey.get(requestCode);
        if (key == null) {
            return false;
        }
        doDispatch(key, resultCode, data, mKeyToCallback.get(key));
        return true;
    }
    private <O> void doDispatch(String key, int resultCode, @Nullable Intent data,
            @Nullable CallbackAndContract<O> callbackAndContract) {
        if (callbackAndContract != null && callbackAndContract.mCallback != null
                && mLaunchedKeys.contains(key)) {
            ActivityResultCallback<O> callback = callbackAndContract.mCallback;
            ActivityResultContract<?, O> contract = callbackAndContract.mContract;
            callback.onActivityResult(contract.parseResult(resultCode, data));
            mLaunchedKeys.remove(key);
        } else {
            // Remove any parsed pending result
            mParsedPendingResults.remove(key);
            // And add these pending results in their place
            mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));
        }
    }

根据requestCode找到key,然后根据下面的callback下发,没有callback就缓存起来;

这里再来看一下Activity重建的操作:

    public final void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putIntegerArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_RCS,
                new ArrayList<>(mKeyToRc.values()));
        outState.putStringArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS,
                new ArrayList<>(mKeyToRc.keySet()));
        outState.putStringArrayList(KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS,
                new ArrayList<>(mLaunchedKeys));
        outState.putBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS,
                (Bundle) mPendingResults.clone());
        outState.putSerializable(KEY_COMPONENT_ACTIVITY_RANDOM_OBJECT, mRandom);
    }

将上面几个数据都存起来;

    public final void onRestoreInstanceState(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            return;
        }
        ArrayList<Integer> rcs =
                savedInstanceState.getIntegerArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_RCS);
        ArrayList<String> keys =
                savedInstanceState.getStringArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS);
        if (keys == null || rcs == null) {
            return;
        }
        mLaunchedKeys =
                savedInstanceState.getStringArrayList(KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS);
        mRandom = (Random) savedInstanceState.getSerializable(KEY_COMPONENT_ACTIVITY_RANDOM_OBJECT);
        mPendingResults.putAll(
                savedInstanceState.getBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS));
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            // Developers may have already registered with this same key by the time we restore
            // state, which caused us to generate a new requestCode that doesn't match what we're
            // about to restore. Clear out the new requestCode to ensure that we use the
            // previously saved requestCode.
            if (mKeyToRc.containsKey(key)) {
                Integer newRequestCode = mKeyToRc.remove(key);
                // On the chance that developers have already called launch() with this new
                // requestCode, keep the mapping around temporarily to ensure the result is
                // properly delivered to both the new requestCode and the restored requestCode
                if (!mPendingResults.containsKey(key)) {
                    mRcToKey.remove(newRequestCode);
                }
            }
            bindRcKey(rcs.get(i), keys.get(i));
        }
    }

在这里做数据还原;

这里一共涉及到五个类型数据的存储和还原。

  • mKeyToRc:key和requestCode;
  • mLaunchedKeys,调用了launch但还没有返回结果;
  • mPendingResults,涉及到Activity时页面重建的缓存;
  • mRandom,这个没看明白作用

看一下这一段:

for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            // Developers may have already registered with this same key by the time we restore
            // state, which caused us to generate a new requestCode that doesn't match what we're
            // about to restore. Clear out the new requestCode to ensure that we use the
            // previously saved requestCode.
            if (mKeyToRc.containsKey(key)) {
                Integer newRequestCode = mKeyToRc.remove(key);
                // On the chance that developers have already called launch() with this new
                // requestCode, keep the mapping around temporarily to ensure the result is
                // properly delivered to both the new requestCode and the restored requestCode
                if (!mPendingResults.containsKey(key)) {
                    mRcToKey.remove(newRequestCode);
                }
            }
            bindRcKey(rcs.get(i), keys.get(i));
        }

着重解释下这块:

第一点就是for循环的最后执行了bindRcKey方法,所有目前是一个key都不会少,哪怕for循环里面remove了这个key,下面也补回来了,只是对应的requestCode变了;

第二点就是mKeyToRc的作用范围,mKeyToRc目前遍历全部代码,在register的时候生成了pair对,然后在调用launch方法的时候,会获取一次requestCode;

而其他很多映射都是和key映射起来的,所以这里把key remove后面再put并没有影响,他只用于launch这里,后面就没它事了;

那这里就有一个问题,有没有可能我在launch后并把requestCode传递出去后,然后执行到了这里;就是有可能存在并行运行,launch和restore运行撞一块了;

存在!!!

那怎么办???

接着看下面的代码:

首先mPendingResults对应一种执行到了dispatch,但是因为对应的Callback为null导致不能回调出去立马执行,便在这里做了一个寄存;

代码中如果mPendingResults他里面不存在对应的key,则说明restore中没有,纯纯重建后新生成的,那就直接移除,用之前的requestCode就行;==我感觉这块代码写错了,应该是mLaunchKey的包含判断!因为mPendingResults的putxxx方法是在业务处理完了才添加进去的,如果是在处理中,也就是在launch到dispatch这段事件中执行到了这,那直接就被移除了,等回调时根本找不到对应的requestCode与key的映射关系;如果是mLaunchKey就解释的通了;在launch的时候添加,在dispatch的时候移除,是一个完整的流程,只要流程没结束这里就不让移除。==

如果mPendingResults里面存在对应的key,那么restore对应的旧的requestCode还需要和key保持映射关系;然后新的requestCode和key也需要存在映射关系,因为可能已经launch出去了;所以这里就存在不同的requestCode对应同一个key的情况;新旧都回调那一个callback。

协议还有一个方法,是关于解析返回结果的:

abstract fun parseResult(resultCode: Int, intent: Intent?): O

这个应该能猜到,是对最后callback返回的数据做了一个过滤层;

看权限申请最终的回调是:

    public void onRequestPermissionsResult(
            int requestCode,
            @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        if (!mActivityResultRegistry.dispatchResult(requestCode, Activity.RESULT_OK, new Intent()
                .putExtra(EXTRA_PERMISSIONS, permissions)
                .putExtra(EXTRA_PERMISSION_GRANT_RESULTS, grantResults))) {
            if (Build.VERSION.SDK_INT >= 23) {
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
        }
    }

跳转Activity的回调是:

    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (!mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

都是调用了:

mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)

而在这里面:

    @MainThread
    public final boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {
        String key = mRcToKey.get(requestCode);
        if (key == null) {
            return false;
        }
        doDispatch(key, resultCode, data, mKeyToCallback.get(key));
        return true;
    }
    private <O> void doDispatch(String key, int resultCode, @Nullable Intent data,
            @Nullable CallbackAndContract<O> callbackAndContract) {
        if (callbackAndContract != null && callbackAndContract.mCallback != null
                && mLaunchedKeys.contains(key)) {
            ActivityResultCallback<O> callback = callbackAndContract.mCallback;
            ActivityResultContract<?, O> contract = callbackAndContract.mContract;
            callback.onActivityResult(contract.parseResult(resultCode, data));
            mLaunchedKeys.remove(key);
        } else {
            // Remove any parsed pending result
            mParsedPendingResults.remove(key);
            // And add these pending results in their place
            mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));
        }
    }

主要是:

callback.onActivityResult(contract.parseResult(resultCode, data));

对返回的数据做了这么一个函数调用解析。

到这涉及到的代码基本都分析完了。


下面是对ActivityResultRegistry整体源码的解析,注释在代码中

/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


 package androidx.activity.result;

 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
 
 import androidx.activity.result.contract.ActivityResultContract;
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.core.app.ActivityOptionsCompat;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleEventObserver;
 import androidx.lifecycle.LifecycleOwner;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
 
 /**
  * A registry that stores {@link ActivityResultCallback activity result callbacks} for
  * {@link ActivityResultCaller#registerForActivityResult registered calls}.
  *
  * You can create your own instance for testing by overriding {@link #onLaunch} and calling
  * {@link #dispatchResult} immediately within it, thus skipping the actual
  * {@link Activity#startActivityForResult} call.
  *
  * When testing, make sure to explicitly provide a registry instance whenever calling
  * {@link ActivityResultCaller#registerForActivityResult}, to be able to inject a test instance.
  */
 public abstract class ActivityResultRegistry {
     //key => requestCode
     //恢复后保存的requestCode 
     private static final String KEY_COMPONENT_ACTIVITY_REGISTERED_RCS =
             "KEY_COMPONENT_ACTIVITY_REGISTERED_RCS";
     //恢复后保存的key
     private static final String KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS =
             "KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS";
     //恢复后保存的 已经launch但是还没有dispatch的key
     private static final String KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS =
             "KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS";
     //dispatch时没有对应的callback和contact时进行保存
     private static final String KEY_COMPONENT_ACTIVITY_PENDING_RESULTS =
             "KEY_COMPONENT_ACTIVITY_PENDING_RESULT";
     //随机数对象保存【这里为啥要保存】
     private static final String KEY_COMPONENT_ACTIVITY_RANDOM_OBJECT =
             "KEY_COMPONENT_ACTIVITY_RANDOM_OBJECT";
 
     //LOG
     private static final String LOG_TAG = "ActivityResultRegistry";
 
     //获取的requestCode 是从65535到Interger.MAX_VALUE
     // Use upper 16 bits for request codes
     private static final int INITIAL_REQUEST_CODE_VALUE = 0x00010000;
     //随机数对象
     private Random mRandom = new Random();
 

    //反向保存【requestCode => key】
    private final Map<Integer, String> mRcToKey = new HashMap<>();
    //正向保存【key => requestCode】
    private final Map<String, Integer> mKeyToRc = new HashMap<>();
    //Lifecycle & Observer 的容器
    private final Map<String, LifecycleContainer> mKeyToLifecycleContainers = new HashMap<>();
    //统计启动了launch的key,dispatch后移除
    ArrayList<String> mLaunchedKeys = new ArrayList<>();

    //key => Callback & Contract 映射
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final transient Map<String, CallbackAndContract<?>> mKeyToCallback = new HashMap<>();

    //两个dispatchResult方法,一个是需要启动Activity然后用来获取Intent返回的数据,另一个不需要启动直接获取数据(类似RequestPermission)

    //dispatch时,如果没有callback 和 contract, 为null时,则将要下发的数值存到这里;这里不需要启动activity时直接存储数据
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Map<String, Object> mParsedPendingResults = new HashMap<>();
    //dispatch时,如果没有callback 和 contract, 为null时,则将要下发的数值存到这里;这里需要启动Activity,需要存储requestCode和intent数据
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Bundle/*<String, ActivityResult>*/ mPendingResults = new Bundle();


    //抽象方法,在ComponentActivity中有具体的实现
     /**
      * Start the process of executing an {@link ActivityResultContract} in a type-safe way,
      * using the provided {@link ActivityResultContract contract}.
      *
      * @param requestCode request code to use
      * @param contract contract to use for type conversions
      * @param input input required to execute an ActivityResultContract.
      * @param options Additional options for how the Activity should be started.
      */
     @MainThread
     public abstract <I, O> void onLaunch(
             int requestCode,
             @NonNull ActivityResultContract<I, O> contract,
             @SuppressLint("UnknownNullness") I input,
             @Nullable ActivityOptionsCompat options);
 
     //Request API注册        
     /**
      * Register a new callback with this registry.
      *
      * This is normally called by a higher level convenience methods like
      * {@link ActivityResultCaller#registerForActivityResult}.
      *
      * @param key a unique string key identifying this call
      * @param lifecycleOwner a {@link LifecycleOwner} that makes this call.
      * @param contract the contract specifying input/output types of the call
      * @param callback the activity result callback
      *
      * @return a launcher that can be used to execute an ActivityResultContract.
      */
     @NonNull
     public final <I, O> ActivityResultLauncher<I> register(
             @NonNull final String key,
             @NonNull final LifecycleOwner lifecycleOwner,
             @NonNull final ActivityResultContract<I, O> contract,
             @NonNull final ActivityResultCallback<O> callback) {
 
         //加入生命周期控制Lifecycle
         Lifecycle lifecycle = lifecycleOwner.getLifecycle();
         //要求注册方法必须要在onStart之前;
         //目的:???
         if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
             throw new IllegalStateException("LifecycleOwner " + lifecycleOwner + " is "
                     + "attempting to register while current state is "
                     + lifecycle.getCurrentState() + ". LifecycleOwners must call register before "
                     + "they are STARTED.");
         }
 
         //根据key随机生成一个requestCode,保证requestCode不重复
         registerKey(key);
         ////组装Lifecycle & Observer 容器
         LifecycleContainer lifecycleContainer = mKeyToLifecycleContainers.get(key);
         if (lifecycleContainer == null) {
             lifecycleContainer = new LifecycleContainer(lifecycle);
         }
         LifecycleEventObserver observer = new LifecycleEventObserver() {
             @Override
             public void onStateChanged(
                     @NonNull LifecycleOwner lifecycleOwner,
                     @NonNull Lifecycle.Event event) {
                 if (Lifecycle.Event.ON_START.equals(event)) {//在onStart状态则将key和Callback映射起来
                     //映射
                     mKeyToCallback.put(key, new CallbackAndContract<>(callback, contract));
                     //因为意外被销毁的数据这里直接执行
                     if (mParsedPendingResults.containsKey(key)) {
                         @SuppressWarnings("unchecked")
                         final O parsedPendingResult = (O) mParsedPendingResults.get(key);
                         mParsedPendingResults.remove(key);
                         callback.onActivityResult(parsedPendingResult);
                     }
                     //因为意外被销毁的数据这里直接执行
                     final ActivityResult pendingResult = mPendingResults.getParcelable(key);
                     if (pendingResult != null) {
                         mPendingResults.remove(key);
                         callback.onActivityResult(contract.parseResult(
                                 pendingResult.getResultCode(),
                                 pendingResult.getData()));
                     }
                 } else if (Lifecycle.Event.ON_STOP.equals(event)) {//在onStop对callback做一个移除,放置后续成功回调但是Activity不在造成泄露
                     mKeyToCallback.remove(key);
                 } else if (Lifecycle.Event.ON_DESTROY.equals(event)) {//反注册
                     unregister(key);
                 }
             }
         };
         //进行订阅
         lifecycleContainer.addObserver(observer);
         //保存
         mKeyToLifecycleContainers.put(key, lifecycleContainer);
 
         //做一个对象返回
         return new ActivityResultLauncher<I>() {
             @Override
             public void launch(I input, @Nullable ActivityOptionsCompat options) {
                 Integer innerCode = mKeyToRc.get(key);
                 if (innerCode == null) {
                     throw new IllegalStateException("Attempting to launch an unregistered "
                             + "ActivityResultLauncher with contract " + contract + " and input "
                             + input + ". You must ensure the ActivityResultLauncher is registered "
                             + "before calling launch().");
                 }
                 //调用启动方法时,加入启动key记录下来
                 mLaunchedKeys.add(key);
                 try {
                     //真正的业务处理
                     onLaunch(innerCode, contract, input, options);
                 } catch (Exception e) {
                     mLaunchedKeys.remove(key);
                     throw e;
                 }
             }
 
             @Override
             public void unregister() {
                 //手动解注册
                 ActivityResultRegistry.this.unregister(key);
             }
 
             @NonNull
             @Override
             public ActivityResultContract<I, ?> getContract() {
                 return contract;
             }
         };
     }
     
     //没有生命周期的注册
     /**
      * Register a new callback with this registry.
      *
      * This is normally called by a higher level convenience methods like
      * {@link ActivityResultCaller#registerForActivityResult}.
      *
      * When calling this, you must call {@link ActivityResultLauncher#unregister()} on the
      * returned {@link ActivityResultLauncher} when the launcher is no longer needed to
      * release any values that might be captured in the registered callback.
      *
      * @param key a unique string key identifying this call
      * @param contract the contract specifying input/output types of the call
      * @param callback the activity result callback
      *
      * @return a launcher that can be used to execute an ActivityResultContract.
      */
     @NonNull
     public final <I, O> ActivityResultLauncher<I> register(
             @NonNull final String key,
             @NonNull final ActivityResultContract<I, O> contract,
             @NonNull final ActivityResultCallback<O> callback) {
         //根据key随机生成requestCode
         registerKey(key);
         //映射callback
         mKeyToCallback.put(key, new CallbackAndContract<>(callback, contract));
 
         //因为意外被销毁的数据这里直接执行
         if (mParsedPendingResults.containsKey(key)) {
             @SuppressWarnings("unchecked")
             final O parsedPendingResult = (O) mParsedPendingResults.get(key);
             mParsedPendingResults.remove(key);
             callback.onActivityResult(parsedPendingResult);
         }
         //因为意外被销毁的数据这里直接执行
         final ActivityResult pendingResult = mPendingResults.getParcelable(key);
         if (pendingResult != null) {
             mPendingResults.remove(key);
             callback.onActivityResult(contract.parseResult(
                     pendingResult.getResultCode(),
                     pendingResult.getData()));
         }
 
         return new ActivityResultLauncher<I>() {
             @Override
             public void launch(I input, @Nullable ActivityOptionsCompat options) {
                 Integer innerCode = mKeyToRc.get(key);
                 if (innerCode == null) {
                     throw new IllegalStateException("Attempting to launch an unregistered "
                             + "ActivityResultLauncher with contract " + contract + " and input "
                             + input + ". You must ensure the ActivityResultLauncher is registered "
                             + "before calling launch().");
                 }
                 mLaunchedKeys.add(key);
                 onLaunch(innerCode, contract, input, options);
             }
 
             @Override
             public void unregister() {
                 ActivityResultRegistry.this.unregister(key);
             }
 
             @NonNull
             @Override
             public ActivityResultContract<I, ?> getContract() {
                 return contract;
             }
         };
     }
 
    //解注册
     /**
      * Unregister a callback previously registered with {@link #register}. This shouldn't be
      * called directly, but instead through {@link ActivityResultLauncher#unregister()}.
      *
      * @param key the unique key used when registering a callback.
      */
     @MainThread
     final void unregister(@NonNull String key) {
         //解注册时如果注册过得key还没有启动,则进行移除【假设是重建,可以在下次request时再注册】
         if (!mLaunchedKeys.contains(key)) {
             // Only remove the key -> requestCode mapping if there isn't a launch in flight
             //双向移除
             Integer rc = mKeyToRc.remove(key);
             if (rc != null) {
                 mRcToKey.remove(rc);
             }
         }
          //callback移除,防止内存泄露
         mKeyToCallback.remove(key);
         //如果是手动触发该方法,说明是主动在做解注册,那就不存在重建的说法;
         //如果是重建触发该方法,这些值会在onSaveInstanceState中进行保存,
         if (mParsedPendingResults.containsKey(key)) {
             Log.w(LOG_TAG, "Dropping pending result for request " + key + ": "
                     + mParsedPendingResults.get(key));
             mParsedPendingResults.remove(key);
         }
         if (mPendingResults.containsKey(key)) {
             Log.w(LOG_TAG, "Dropping pending result for request " + key + ": "
                     + mPendingResults.<ActivityResult>getParcelable(key));
             mPendingResults.remove(key);
         }
         //解除生命周期订阅
         LifecycleContainer lifecycleContainer = mKeyToLifecycleContainers.get(key);
         if (lifecycleContainer != null) {
             lifecycleContainer.clearObservers();
             mKeyToLifecycleContainers.remove(key);
         }
     }
 
     //Activity重建时会对这些数据进行保存
     /**
      * Save the state of this registry in the given {@link Bundle}
      *
      * @param outState the place to put state into
      */
     public final void onSaveInstanceState(@NonNull Bundle outState) {
         //requestCode
         outState.putIntegerArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_RCS,
                 new ArrayList<>(mKeyToRc.values()));
         //key
         outState.putStringArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS,
                 new ArrayList<>(mKeyToRc.keySet()));
         //mLaunchedKeys 用来做标记移除的
         outState.putStringArrayList(KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS,
                 new ArrayList<>(mLaunchedKeys));
         //用来做恢复的
         outState.putBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS,
                 (Bundle) mPendingResults.clone());
         //省内存???
         outState.putSerializable(KEY_COMPONENT_ACTIVITY_RANDOM_OBJECT, mRandom);
     }
 
     //恢复数据
     /**
      * Restore the state of this registry from the given {@link Bundle}
      *
      * @param savedInstanceState the place to restore from
      */
     public final void onRestoreInstanceState(@Nullable Bundle savedInstanceState) {
         if (savedInstanceState == null) {
             return;
         }
         //重新构建key => requestCode的映射表
         ArrayList<Integer> rcs =
                 savedInstanceState.getIntegerArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_RCS);
         ArrayList<String> keys =
                 savedInstanceState.getStringArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS);
         if (keys == null || rcs == null) {
             return;
         }
         mLaunchedKeys =
                 savedInstanceState.getStringArrayList(KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS);
         mRandom = (Random) savedInstanceState.getSerializable(KEY_COMPONENT_ACTIVITY_RANDOM_OBJECT);
         mPendingResults.putAll(
                 savedInstanceState.getBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS));
         //着重解释下这块:
         //第一点就是for循环的最后执行了bindRcKey方法,所有目前是一个key都不会少,哪怕for循环里面remove了这个key,下面也补回来了,只是对应的requestCode变了;
         //第二点就是mKeyToRc的作用范围,mKeyToRc目前遍历全部代码,在注册的时候生成了pair对,然后在调用launch方法的时候,会获取一次requestCode;
         //而其他很多映射都是和key映射起来的,所以这里把key remove后面再put并没有影响,他只用于launch这里,后面就没它事了;
         //那这里就有一个问题,有没有可能我在launch后把requestCode传递出去后,然后执行到了这里;就是有可能存在并行运行,launch和restore运行撞一块了;
         //存在!!!
         //那怎么办???
         //接着看下面的代码:
         //mPendingResults对应一种执行到了dispatch,但是因为对应的Callback导致不能回调出去立马执行,边在这里做了一个寄存;
         //如果他里面不存在对应的key,则说明restore中没有,纯纯新生成的;我感觉这块代码写错了,应该是mLaunchKey的包含判断!
         //如果它里面存在对应key,那么restore对应的旧的requestCode还需要和key保持映射关系;然后新的requestCode和key也需要存在映射关系,因为可能已经launch出去了;所以这里就存在不同的requestCode对应同一个key的情况;新旧都回调那一个callback
         for (int i = 0; i < keys.size(); i++) {
             String key = keys.get(i);
             // Developers may have already registered with this same key by the time we restore
             // state, which caused us to generate a new requestCode that doesn't match what we're
             // about to restore. Clear out the new requestCode to ensure that we use the
             // previously saved requestCode.
             if (mKeyToRc.containsKey(key)) {
                 Integer newRequestCode = mKeyToRc.remove(key);
                 // On the chance that developers have already called launch() with this new
                 // requestCode, keep the mapping around temporarily to ensure the result is
                 // properly delivered to both the new requestCode and the restored requestCode
                 if (!mPendingResults.containsKey(key)) {
                     mRcToKey.remove(newRequestCode);
                 }
             }
             bindRcKey(rcs.get(i), keys.get(i));
         }
     }
 
     //对应需要启动Activity后返回的数据处理
     /**
      * Dispatch a result received via {@link Activity#onActivityResult} to the callback on record,
      * or store the result if callback was not yet registered.
      *
      * @param requestCode request code to identify the callback
      * @param resultCode status to indicate the success of the operation
      * @param data an intent that carries the result data
      *
      * @return whether there was a callback was registered for the given request code which was
      * or will be called.
      */
     @MainThread
     public final boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {
         String key = mRcToKey.get(requestCode);
         if (key == null) {
             return false;
         }
         //具体的业务处理
         doDispatch(key, resultCode, data, mKeyToCallback.get(key));
         return true;
     }
 
     //对用不需要启动Activity就返回的数据处理
     /**
      * Dispatch a result object to the callback on record.
      *
      * @param requestCode request code to identify the callback
      * @param result the result to propagate
      *
      * @return true if there is a callback registered for the given request code, false otherwise.
      */
     @MainThread
     public final <O> boolean dispatchResult(int requestCode,
             @SuppressLint("UnknownNullness") O result) {
         String key = mRcToKey.get(requestCode);
         if (key == null) {
             return false;
         }
 
         //拿到key映射的callback
         CallbackAndContract<?> callbackAndContract = mKeyToCallback.get(key);
         if (callbackAndContract == null || callbackAndContract.mCallback == null) {
             // Remove any pending result
             mPendingResults.remove(key);
             // And add these pre-parsed pending results in their place
             mParsedPendingResults.put(key, result);
         } else {
             //直接下发
             @SuppressWarnings("unchecked")
             ActivityResultCallback<O> callback =
                     (ActivityResultCallback<O>) callbackAndContract.mCallback;
             //用完就删
             if (mLaunchedKeys.remove(key)) {
                 callback.onActivityResult(result);
             }
         }
         return true;
     }
 
     //对启动Activity返回数据的处理
     private <O> void doDispatch(String key, int resultCode, @Nullable Intent data,
             @Nullable CallbackAndContract<O> callbackAndContract) {
         if (callbackAndContract != null && callbackAndContract.mCallback != null
                 && mLaunchedKeys.contains(key)) {
             //存在callback则直接下发
             ActivityResultCallback<O> callback = callbackAndContract.mCallback;
             ActivityResultContract<?, O> contract = callbackAndContract.mContract;
             callback.onActivityResult(contract.parseResult(resultCode, data));
             //用完就删
             mLaunchedKeys.remove(key);
         } else {
             //不存在则直接存储起来(可能因为其他原因重建了???)
             // Remove any parsed pending result
             mParsedPendingResults.remove(key);
             // And add these pending results in their place
             mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));
         }
     }
 
     //构建requestCode,并生成key => requestCode映射表
     private void registerKey(String key) {
         Integer existing = mKeyToRc.get(key);
         if (existing != null) {
             return;
         }
         int rc = generateRandomNumber();
         bindRcKey(rc, key);
     }
 
     //生成一个唯一的
     /**
      * Generate a random number between the initial value (00010000) inclusive, and the max
      * integer value. If that number is already an existing request code, generate another until
      * we find one that is new.
      *
      * @return the number
      */
     private int generateRandomNumber() {
         int number = mRandom.nextInt((Integer.MAX_VALUE - INITIAL_REQUEST_CODE_VALUE) + 1)
                 + INITIAL_REQUEST_CODE_VALUE;
         while (mRcToKey.containsKey(number)) {
             number = mRandom.nextInt((Integer.MAX_VALUE - INITIAL_REQUEST_CODE_VALUE) + 1)
                     + INITIAL_REQUEST_CODE_VALUE;
         }
         return number;
     }
 
     //做映射存储
     private void bindRcKey(int rc, String key) {
         mRcToKey.put(rc, key);
         mKeyToRc.put(key, rc);
     }
 
     //容器
     private static class CallbackAndContract<O> {
         final ActivityResultCallback<O> mCallback;
         final ActivityResultContract<?, O> mContract;
 
         CallbackAndContract(
                 ActivityResultCallback<O> callback,
                 ActivityResultContract<?, O> contract) {
             mCallback = callback;
             mContract = contract;
         }
     }
 
     //容器
     private static class LifecycleContainer {
         final Lifecycle mLifecycle;
         private final ArrayList<LifecycleEventObserver> mObservers;
 
         LifecycleContainer(@NonNull Lifecycle lifecycle) {
             mLifecycle = lifecycle;
             mObservers = new ArrayList<>();
         }
 
         void addObserver(@NonNull LifecycleEventObserver observer) {
             mLifecycle.addObserver(observer);
             mObservers.add(observer);
         }
 
         void clearObservers() {
             for (LifecycleEventObserver observer: mObservers) {
                 mLifecycle.removeObserver(observer);
             }
             mObservers.clear();
         }
     }
 }