`Android`优雅的封装`ActivityResultLauncher`启动活动和请求权限,外加处理意外被`kill`情况

`Android`优雅的封装`ActivityResultLauncher`启动活动和请求权限,外加处理意外被`kill`情况,第1张

Android优雅的封装ActivityResultLauncher启动活动和请求权限

一般我们在请求权限或者处理Activity返回结果的时候都会使用Activity#onActivityResult()Activity#onRequestPermissionResult()这俩个方法,如今谷歌已经提供了新的请求方法:https://developer.android.com/training/permissions/requesting?hl=zh-cn。

这篇文章是解决什么的?
我想把每个处理结果回调的代码块直接写在ActivityResultLauncher.launch()方法中(1)中的问题:ActivityResultLauncher对象要用ActivityResultCaller#registerForActivityResult()得到(2)中的问题:注册必须在Activity#onStart()方法之前处理意外情况:Activity_A启动另一个activity_B,然后A意外被kill掉了,这时候从B返回了,A重新创建了,原先注册的地方不会执行回调
开始上代码,准备动手 首先解决这个registerForActivityResult()方法要在onStart()之前调用

直接在Activity#onCreate()中拿到ActivityResultLauncher对象,并且将回调写好

open class BaseActivityResultLauncher<I, O>(
    caller: ActivityResultCaller,
    contract: ActivityResultContract<I, O>
) {
    private var launcher: ActivityResultLauncher<I>
    private lateinit var callback: ActivityResultCallback<O>

    init {
        launcher = caller.registerForActivityResult(contract) { result ->
           	// ---- 1----
            callback.onActivityResult(result)
        }
    }

    // 在调用launch的时候把callback传入进去,然后结果回调会走 1 处代码
    open fun launch(
        input: I,
        callback: ActivityResultCallback<O>
    ) {
        this.callback = callback
        launcher.launch(input)
    }
}

定义一些常用的ActivityResultLauncher,可以看系统的ActivityResultContracts,参考着抄一遍

class SinglePermissionLauncher(
    caller: ActivityResultCaller
): BaseActivityResultLauncher<String, Boolean>(
    caller,
    ActivityResultContracts.RequestPermission()
)

class MultiPermissionsLauncher(
    caller: ActivityResultCaller
): BaseActivityResultLauncher<Array<String>, MutableMap<String, Boolean>>(
    caller,
    ActivityResultContracts.RequestMultiplePermissions()
)

class StartActivityForResultLauncher(
    caller: ActivityResultCaller
): BaseActivityResultLauncher<Intent, ActivityResult>(
    caller,
    ActivityResultContracts.StartActivityForResult()
)
现在开始封装(抽出来一个BaseActivity
BaseActivity {
	private lateinit var singlePermissionLauncher: SinglePermissionLauncher
    private lateinit var multiPermissionLauncher: MultiPermissionsLauncher
    private lateinit var startForResultLauncher: StartActivityForResultLauncher
    
    override fun onCreate(savedInstanceState: Bundle?) {
    	singlePermissionLauncher = SinglePermissionLauncher(this)
        multiPermissionLauncher = MultiPermissionsLauncher(this)
        startForResultLauncher = StartActivityForResultLauncher(this)
    }
    
    /**
     * 请求单个权限
     *
     * @param permission String
     * @param callback
     */
    fun requestSinglePermission(
        permission: String,
        callback: (isGranted: Boolean, shouldShowRequestPermissionRationale: Boolean) -> Unit) {
        singlePermissionLauncher.launch(permission) {
            callback(it, shouldShowRequestPermissionRationale(permission))
        }
    }

    /**
     * 同时请求多个权限
     *
     * @param permissions Array
     * @param callback
     */
    fun requestMultiPermissions(
        permissions: Array<String>,
        callback: (
            isAllGranted: Boolean,
            grantedList: List<String>,
            deniedList: List<String>,
            alwaysDeniedList: List<String>
        ) -> Unit
    ) {
        multiPermissionLauncher.launch(permissions) {
            val grantedList = it.filterValues { it }.mapNotNull { it.key }
            val leftoverList = (it - grantedList).map { it.key }
            val deniedList = leftoverList.filter { shouldShowRequestPermissionRationale(it) }
            callback(grantedList.size == it.size, grantedList,
                deniedList, leftoverList - deniedList)
        }
    }

    /**
     * 代替 [AppCompatActivity.startActivityForResult]
     *
     * @param intent Intent
     * @param callback ActivityResultCallback
     */
    fun startActivityForResult(
        intent: Intent,
        callback: (requestCode: Int, data: Intent?) -> Unit
    ) {
        startForResultLauncher.launch(intent) {
            callback(it.resultCode, it.data)
        }
    }
}
使用
activity.requestMultiPermissions(permissions) { isAllGranted, _, _, _ ->
       // 具体的回调代码逻辑
}
处理极端情况:原先发起请求的Activity被意外Kill了,我之前写的callback咋办? 核心处理方法:自定义一个保存注册回调的注册表,然后仿照系统的Activity处理流程把onStart()之前注册的逻辑屏蔽掉,让我们的注册可以在onResume()之后,并且将处理意外情况要保存的数据保存到onSaveInstanceState()中(androidx.activity.result.ActivityResultRegistry
    // =================  屏蔽这里的代码 =============================

    /*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.");
    }*/


// =================  屏蔽这里的代码 =============================
public abstract class LazyActivityResultRegistry {
    private static final String KEY_COMPONENT_ACTIVITY_REGISTERED_RCS =
            "KEY_COMPONENT_ACTIVITY_REGISTERED_RCS";
    private static final String KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS =
            "KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS";
    private static final String KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS =
            "KEY_COMPONENT_ACTIVITY_LAUNCHED_KEYS";
    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";

    private static final String LOG_TAG = "ActivityResultRegistry";

    private static final int INITIAL_REQUEST_CODE_VALUE = 0x00010000;
    private Random mRandom = new Random();

    private final Map<Integer, String> mRcToKey = new HashMap<>();
    final Map<String, Integer> mKeyToRc = new HashMap<>();
    private final Map<String, LifecycleContainer> mKeyToLifecycleContainers = new HashMap<>();
    ArrayList<String> mLaunchedKeys = new ArrayList<>();

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

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Map<String, Object> mParsedPendingResults = new HashMap<>();
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Bundle/**/ mPendingResults = new Bundle();

    @MainThread
    public abstract <I, O> void onLaunch(
            int requestCode,
            @NonNull ActivityResultContract<I, O> contract,
            @SuppressLint("UnknownNullness") I input,
            @Nullable ActivityOptionsCompat options);

    @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);
                Integer innerCode = mKeyToRc.get(key);
                onLaunch((innerCode != null) ? innerCode : requestCode, contract, input, options);
            }

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

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

   
    @NonNull
    public final <I, O> ActivityResultLauncher<I> register(
            @NonNull final String key,
            @NonNull final ActivityResultContract<I, O> contract,
            @NonNull final ActivityResultCallback<O> callback) {
        final int requestCode = registerKey(key);
        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) {
                mLaunchedKeys.add(key);
                Integer innerCode = mKeyToRc.get(key);
                onLaunch((innerCode != null) ? innerCode : requestCode, contract, input, options);
            }

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

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

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

    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);
           
            if (mKeyToRc.containsKey(key)) {
               
                if (!mPendingResults.containsKey(key)) {
                    mRcToKey.remove(newRequestCode);
                }
            }
            bindRcKey(rcs.get(i), keys.get(i));
        }
    }

    @MainThread
    public final boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {
        String key = mRcToKey.get(requestCode);
        if (key == null) {
            return false;
        }
        mLaunchedKeys.remove(key);

        doDispatch(key, resultCode, data, mKeyToCallback.get(key));
        return true;
    }

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

        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;
            callback.onActivityResult(result);
        }
        return true;
    }

    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;
            callback.onActivityResult(contract.parseResult(resultCode, data));
        } else {
            // Remove any parsed pending result
            mParsedPendingResults.remove(key);
            // And add these pending results in their place
            mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));
        }
    }

    private int registerKey(String key) {
        Integer existing = mKeyToRc.get(key);
        if (existing != null) {
            return existing;
        }
        int rc = generateRandomNumber();
        bindRcKey(rc, key);
        return rc;
    }

    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();
        }
    }
}
抽象出来一个Activity
abstract class LazyRegisterActivity : FragmentActivity(), INoteActivity {

    private val mActivityCallbacks = mutableListOf<INoteActivity.ActivityCallbacks>()

    var isLoadComplete: Boolean by Delegates.observable(false) { _, old, new ->
        if (new != old) {
            pendingResultMap.forEach { (_, data) ->
                noteActivityResultRegistry.dispatchResult(data.requestCode,
                        data.resultCode, data.data)
            }
            pendingResultMap.clear()
        }
    }

    private val nextLocalRequestCode = AtomicInteger()

    private data class ResultData(val requestCode: Int, val resultCode: Int, val data: Intent?)

    private val pendingResultMap = mutableMapOf<Int, ResultData>()

    // copy from ComponentActivity
    private val customActivityResultRegistry: LazyActivityResultRegistry = object : LazyActivityResultRegistry() {
        override fun <I, O> onLaunch(
                requestCode: Int,
                contract: ActivityResultContract<I, O>,
                input: I,
                options: ActivityOptionsCompat?) {
            val activity: ComponentActivity = this@LazyRegisterActivity

            // Immediate result path
            val synchronousResult = contract.getSynchronousResult(activity, input)
            if (synchronousResult != null) {
                Handler(Looper.getMainLooper()).post { dispatchResult(requestCode, synchronousResult.value) }
                return
            }

            // Start activity path
            val intent = contract.createIntent(activity, input)
            var optionsBundle: Bundle? = null
            // If there are any extras, we should defensively set the classLoader
            if (intent.extras != null && intent.extras!!.classLoader == null) {
                intent.setExtrasClassLoader(activity.classLoader)
            }
            if (intent.hasExtra(ActivityResultContracts.StartActivityForResult.EXTRA_ACTIVITY_OPTIONS_BUNDLE)) {
                optionsBundle = intent.getBundleExtra(ActivityResultContracts.StartActivityForResult.EXTRA_ACTIVITY_OPTIONS_BUNDLE)
                intent.removeExtra(ActivityResultContracts.StartActivityForResult.EXTRA_ACTIVITY_OPTIONS_BUNDLE)
            } else if (options != null) {
                optionsBundle = options.toBundle()
            }
            when {
                ActivityResultContracts.RequestMultiplePermissions.ACTION_REQUEST_PERMISSIONS == intent.action -> {
                    // requestPermissions path
                    var permissions = intent.getStringArrayExtra(ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSIONS)
                    if (permissions == null) {
                        permissions = arrayOfNulls(0)
                    }
                    ActivityCompat.requestPermissions(activity, permissions, requestCode)
                }
                ActivityResultContracts.StartIntentSenderForResult.ACTION_INTENT_SENDER_REQUEST == intent.action -> {
                    val request: IntentSenderRequest = intent.getParcelableExtra(ActivityResultContracts.StartIntentSenderForResult.EXTRA_INTENT_SENDER_REQUEST)!!
                    try {
                        // startIntentSenderForResult path
                        ActivityCompat.startIntentSenderForResult(activity, request.intentSender,
                                requestCode, request.fillInIntent, request.flagsMask,
                                request.flagsValues, 0, optionsBundle)
                    } catch (e: SendIntentException) {
                        Handler(Looper.getMainLooper()).post {
                            dispatchResult(requestCode, RESULT_CANCELED,
                                    Intent().setAction(ActivityResultContracts.StartIntentSenderForResult.ACTION_INTENT_SENDER_REQUEST)
                                            .putExtra(ActivityResultContracts.StartIntentSenderForResult.EXTRA_SEND_INTENT_EXCEPTION, e))
                        }
                    }
                }
                else -> {
                    // startActivityForResult path
                    ActivityCompat.startActivityForResult(activity, intent, requestCode, optionsBundle)
                }
            }
        }
    }

    companion object {
        private const val ACTIVITY_RESULT_TAG = "note:activity-result"
    }

    override fun registerActivityCallbacks(callback: INoteActivity.ActivityCallbacks) {
        synchronized(mActivityCallbacks) { mActivityCallbacks.add(callback) }
        registerActivityLifecycleCallbacks(callback)
    }

    override fun unregisterActivityCallbacks(callback: INoteActivity.ActivityCallbacks) {
        synchronized(mActivityCallbacks) { mActivityCallbacks.remove(callback) }
        unregisterActivityLifecycleCallbacks(callback)
    }

    @CallSuper
    override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration) {
        super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
        synchronized(mActivityCallbacks) {
            mActivityCallbacks.forEach {
                it.onMultiWindowModeChanged(this, isInMultiWindowMode, newConfig)
            }
        }
    }

    @CallSuper
    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        synchronized(mActivityCallbacks) {
            mActivityCallbacks.forEach {
                it.onWindowFocusChanged(this, hasFocus)
            }
        }
    }

    @CallSuper
    override fun onDestroy() {
        super.onDestroy()
        synchronized(mActivityCallbacks) { mActivityCallbacks.clear() }
    }

    @CallSuper
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (isLoadComplete) {
            customActivityResultRegistry.dispatchResult(requestCode, resultCode, data)
        } else {
            pendingResultMap[requestCode] = ResultData(requestCode, resultCode, data)
        }
    }

    override fun <I, O> registerForLazyActivityResult(contract: ActivityResultContract<I, O>,
                                                      callback: ActivityResultCallback<O>): ActivityResultLauncher<I> {
        if (isLoadComplete) {
            throw Throwable("can only register before load complete!")
        }
        return customActivityResultRegistry.register(
                "activity_rq#" + nextLocalRequestCode.getAndIncrement(),
                this, contract, callback)
    }

    override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        val data = Intent()
                .putExtra(ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSIONS, permissions)
                .putExtra(ActivityResultContracts.RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS, grantResults)
        if (isLoadComplete) {
            customActivityResultRegistry.dispatchResult(requestCode, RESULT_OK, data)
        } else {
            pendingResultMap[requestCode] = ResultData(requestCode, RESULT_OK, data)
        }
    }

    init {
        savedStateRegistry.registerSavedStateProvider(ACTIVITY_RESULT_TAG
        ) {
            val outState = Bundle()
            customActivityResultRegistry.onSaveInstanceState(outState)
            outState
        }
        addOnContextAvailableListener {
            val savedInstanceState = savedStateRegistry
                    .consumeRestoredStateForKey(ACTIVITY_RESULT_TAG)
            if (savedInstanceState != null) {
                customActivityResultRegistry.onRestoreInstanceState(savedInstanceState)
            }
        }
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/992203.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)