过时的OnActivityResult(二)

2021-03-17  本文已影响0人  浪够_

针对上篇《过时的OnActivityResult一》,本篇进行源码解析:

先来看一下在Activity中启动launcher之后是怎么实现这种功能的

调用ComponentActivity中的registerForActivityResult,该方法返回一个ActivityResultLauncher用于启动Intent

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);
}

由于没有自定义ActivityResultRegistry,所以这里使用的是ComponentActivity中的mActivityResultRegistry,调用了ActivityResultRegistry中的register

register则使用了lifecycleOwner实现了自动解绑功能,然后返回了一个ActivityResultLauncher,并调用了invoke方法

public final <I, O> ActivityResultLauncher<I> register() {
        // 注册一个requestCode并保存回调,这里的回调就是在onActivityResult拦截的时候取的
        final int requestCode = registerKey(key);
        mKeyToCallback.put(key, new CallbackAndContract<>(callback, contract));
        // 这里最终返回的是我们需要的ActivityResultLauncher,并调用了ComponentActivity中mActivityResultRegistry的invoke
        return new ActivityResultLauncher<I>() {
            @Override
            public void launch(I input, @Nullable ActivityOptionsCompat options) {
                invoke(requestCode, contract, input, options);
            }

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

这个时候回到ComponentActivity的mActivityResultRegistry看下源码就知道是怎么一回事了,该方法先判断了action是否为权限或者支付,最后调用的startActivityForResult

private ActivityResultRegistry mActivityResultRegistry = new ActivityResultRegistry() {
        @Override
        public <I, O> void invoke() {
            ComponentActivity activity = ComponentActivity.this;
            Intent intent = contract.createIntent(activity, input);
            if (ACTION_REQUEST_PERMISSIONS.equals(intent.getAction())) {
                // requestPermissions path  权限处理
            } else if (ACTION_INTENT_SENDER_REQUEST.equals(intent.getAction())) {
                //google支付
            } else {
                // 启动activity最终调用的是这里
                ActivityCompat.startActivityForResult(activity, intent, requestCode, options != null ? options.toBundle() : null);
            }
        }
 };

具体流程大概是这个样子,再来看下是如何拦截onActivityResult的

ActivityResultRegistry拦截了onActivityResult,onRequestPermissionsResult同理,dispatchResult方法判断了是否需要拦截,根据在调用register的时候保存的registerkey来判断

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    //处理onActivityResult如果不是launcher启动的则还是走onActivityResult
    //不过这里已经标记为过时
    if (!mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)) {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

然后拿出mKeyToCallback中保存对应requestCode的回调ActivityResultCallback,这个时候调用ActivityResultCallback的onActivityResult,这样就能拿到对应的数据和状态

public final boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {
    String key = mRcToKey.get(requestCode);
    if (key == null) {
        //使用的startActivityForResult
        return false;
    }
    doDispatch(key, resultCode, data, mKeyToCallback.get(key));
    return true;
}

//这里就比较简单了,获取回调之后返回parseResult生成的类数据
private <O> void doDispatch(String key, int resultCode, @Nullable Intent data, @Nullable CallbackAndContract<O> callbackAndContract) {
    if (callbackAndContract != null && callbackAndContract.mCallback != null) {
        ActivityResultCallback<O> callback = callbackAndContract.mCallback;
        ActivityResultContract<?, O> contract = callbackAndContract.mContract;
        //parseResult返回的什么这里就获取的什么
        callback.onActivityResult(contract.parseResult(resultCode, data));
    } else {
        mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));
    }
}

fragment也是先拿到mActivityResultRegistry然后还是走的Activity流程

public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
        @NonNull final ActivityResultContract<I, O> contract,
        @NonNull final ActivityResultCallback<O> callback) {
    return prepareCallInternal(contract, new Function<Void, ActivityResultRegistry>() {
        @Override
        public ActivityResultRegistry apply(Void input) {
            //返回了ComponentActivity的ActivityResultRegistry
            if (mHost instanceof ActivityResultRegistryOwner) {
                return ((ActivityResultRegistryOwner) mHost).getActivityResultRegistry();
            }
            return requireActivity().getActivityResultRegistry();
        }
    }, callback);
}
上一篇下一篇

猜你喜欢

热点阅读