Activity Result API 使用与源码分析,面试阿里P7岗

2022/1/17 11:34:21

本文主要是介绍Activity Result API 使用与源码分析,面试阿里P7岗,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

public final <I, O> ActivityResultLauncher register(

@NonNull final String key,

@NonNull final LifecycleOwner lifecycleOwner,

@NonNull final ActivityResultContract<I, O> con
tract,

@NonNull final ActivityResultCallback callback) {

Lifecycle lifecycle = lifecycleOwner.getLifecycle();

//每个请求的key也不一样,根据key生成一个唯一的requestCode

final int requestCode = registerKey(key);

//把lifecycle和observer统一封装到LifecycleContainer中

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

}

//从bundle中获取结果

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);//stop时移除

} else if (Lifecycle.Event.ON_DESTROY.equals(event)) {

unregister(key);//destory时注销

}

}

};

//添加观察者

lifecycleContainer.addObserver(observer);

mKeyToLifecycleContainers.put(key, lifecycleContainer);

//返回ActivityResultLauncher对象

return new ActivityResultLauncher() {

@Override

public void launch(I input, @Nullable ActivityOptionsCompat options) {

mLaunchedKeys.add(key);

//ActivityResultRegistry的onLaunch,抽象方法,在ComponentActivity内实现

onLaunch(requestCode, contract, input, options);

}

public void unregister() {

ActivityResultRegistry.this.unregister(key);

}

public ActivityResultContract<I, ?> getContract() {

return contract;

}

};

}

2.launch

ActivityResultRegistryonLaunch是一个抽象方法,在ComponentActivity内实现。首先会检查contract是否能获取同步结果,如果能,则直接分发处理。比如权限申请,我前面已经获取了权限,直接可以通过getSynchronousResult查询是否有权限。有直接返回true,不再通过requestPermissions去做申请权限。

在通过contract获取Intent,按Intent分为三种情况处理,第一种,权限申请,通过requestPermissions去申请权限,第二种处理INTENT_SENDER,和startIntentSenderForResult类似。第三种,处理其它问题,通过startActivityForResult启动Activity

public <I, O> void onLaunch(

final int requestCode,

@NonNull ActivityResultContract<I, O> contract,

I input,

@Nullable ActivityOptionsCompat options) {

ComponentActivity activity = ComponentActivity.this;

//如果能直接拿到结果,直接分发处理了。

final ActivityResultContract.SynchronousResult synchronousResult =

contract.getSynchronousResult(activity, input);

if (synchronousResult != null) {

new Handler(Looper.getMainLooper()).post(new Runnable() {

@Override

public void run() {

dispatchResult(requestCode, synchronousResult.getValue());

}

});

return;

}

// 根据协定创建Intent对象

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())) {

//处理StartIntentSenderForResult

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) {

}

} else {

//其它普通问题启动Activity

ActivityCompat.startActivityForResult(activity, intent, requestCode, optionsBundle);

}

}

3.结果回调

ComponentActivity中,onActivityResult和onRequestPermissionsResult方法会先被ActivityResultRegistry的dispatchResult方法拦截,如果它能处理,则不再调用Activity的方法。

dispatchResult会调用doDispatch来处理结果,这有两种情况,通过keymKeyToCallback中获取callbackAndContract对象,如果不为空,则直接回调结果。比如权限申请,不会走ON_STOP事件,mKeyToCallback不会被清除,这里就不会为空。如果为空则把结果放到mPendingResults这个Bundle对象中,和前面的ON_START事件对应起来,从mPendingResults取出结果,回调结果。

-ComponentActivity.java

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

if (!mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)) {

super.onActivityResult(requestCode, resultCode, data);

}

}

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

}

}

}

  • ActivityResultRegistry.java

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;

}

private void doDispatch(String key, int resultCode, @Nullable Intent data,

@Nullable CallbackAndContract callbackAndContract) {

callbackAndContract不为空则直接回调即可

if (callbackAndContract != null && callbackAndContract.mCallback != null) {

ActivityResultCallback callback = callbackAndContract.mCallback;

ActivityResultContract<?, O> contract = callbackAndContract.mContract;

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

act callbackAndContract) {

callbackAndContract不为空则直接回调即可

if (callbackAndContract != null && callbackAndContract.mCallback != null) {

ActivityResultCallback callback = callbackAndContract.mCallback;

ActivityResultContract<?, O> contract = callbackAndContract.mContract;

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



这篇关于Activity Result API 使用与源码分析,面试阿里P7岗的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程