Android深入学习之ComponentActivity.registerForActivityResult()方法
ComponentActivity.startActivityForResult()和ComponentActivity.onActivityResult()已经废弃,如下图所示,取而代之的是统一它俩的ActivityResultLauncher。
ActivityResultLauncher对象可以通过ComponentActivity.registerForActivityResult()方法获取。该方法有两个重载。
public final @NonNull ActivityResultLauncher<I> <I, O> registerForActivityResult( @NonNull ActivityResultContract<I, O> contract, @NonNull ActivityResultCallback<O> callback ) public final @NonNull ActivityResultLauncher<I> <I, O> registerForActivityResult( @NonNull ActivityResultContract<I, O> contract, @NonNull ActivityResultRegistry registry, @NonNull ActivityResultCallback<O> callback )
第一个registerForActivityResult()方法的源代码如下:
@NonNull @Override public final <I, O> ActivityResultLauncher<I> registerForActivityResult( @NonNull ActivityResultContract<I, O> contract, @NonNull ActivityResultCallback<O> callback) { return registerForActivityResult(contract, mActivityResultRegistry, callback); }
它拿着mActivityResultRegistry对象去调用了第二个registerForActivityResult()方法。第二个registerForActivityResult()方法的源代码如下:
@NonNull @Override 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); }
mActivityResultRegistry是ComponentActivity中定义并初始化的一个ActivityResultRegistry类型变量。
ActivityResultRegistry是个抽象类,其中定义的抽象方法是
@MainThread public abstract void <I, O> onLaunch( int requestCode, @NonNull ActivityResultContract<I, O> contract, I input, @Nullable ActivityOptionsCompat options )
此外还有两个被final修饰的register()方法
public final @NonNull ActivityResultLauncher<I> <I, O> register( @NonNull String key, @NonNull ActivityResultContract<I, O> contract, @NonNull ActivityResultCallback<O> callback ) public final @NonNull ActivityResultLauncher<I> <I, O> register( @NonNull String key, @NonNull LifecycleOwner lifecycleOwner, @NonNull ActivityResultContract<I, O> contract, @NonNull ActivityResultCallback<O> callback )
上方registerForActivityResult()方法就是调用了第二个register()方法,源代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@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."); } registerKey(key); LifecycleContainer lifecycleContainer = mKeyToLifecycleContainers.get(key); if (lifecycleContainer == null) { lifecycleContainer = new LifecycleContainer(lifecycle); } LifecycleEventObserver observer = new LifecycleEventObserver() { @Override @SuppressWarnings("deprecation") 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) { 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); 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; } }; }
其中,下方代码就说明了官方文档的那句
registerForActivityResult() must be called unconditionally, as part of initialization path, typically as a field initializer of an Activity or Fragment.
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."); }
即,registerForActivityResult()需要在Activity的状态是STARTED之前被调用。也就是,在定义ActivityResultLauncher变量时,或者在构造函数里,或者在onCreate()/onStart()方法里。