ActivityResultContractActivity 1.2.0-alpha02Fragment 1.3.0-alpha02 中新追加的API,可以更加方便且typeSafe地处理startActivityForResult


如何使用


AppCompatActivity和Fragment中可以通过prepareCall()创建launcher,然后调用launch(intent)进行startActivityForResult

//MainActivity.ktval intent = Intent(this, SecondActivity::class.java)val launcher: ActivityResultLauncher<Intent> = prepareCall(        ActivityResultContracts.StartActivityForResult()) { activityResult: ActivityResult ->    Log.d("MainActivity", activityResult.toString())    //  D/MainActivity: ActivityResult{resultCode=RESULT_OK, data=Intent { (has extras) }}}fab.setOnClickListener { view ->    launcher.launch(intent)}
//SecondActivity.ktclass SecondActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setResult(Activity.RESULT_OK, Intent().putExtra("my-data", "data"))        finish()    }}

ActivityResultContracts相关实现


StartActivityForResult

prepareCall()中传入ActivityResultContracts.StartActivityForResult的实例,它继承自 ActivityResultContract

// ActivityResultContracts.javapublic class ActivityResultContracts {    private ActivityResultContracts() {}...    public static class StartActivityForResult            extends ActivityResultContract<Intent, ActivityResult> {        @NonNull        @Override        public Intent createIntent(@NonNull Intent input) {            return input;        }        @NonNull        @Override        public ActivityResult parseResult(int resultCode, @Nullable Intent intent) {            return new ActivityResult(resultCode, intent);        }    }

当然替换为匿名类的写法也OK,如下

val launcher: ActivityResultLauncher<Intent> = prepareCall(        // ** ↓ **        object : ActivityResultContract<Intent, ActivityResult>() {            override fun createIntent(input: Intent): Intent {                return input            }            override fun parseResult(resultCode: Int, intent: Intent?): ActivityResult {                return ActivityResult(resultCode, intent)            }        }        // ** ↑ **) { activityResult: ActivityResult ->    Log.d("MainActivity", activityResult.toString())    //  D/MainActivity: ActivityResult{resultCode=RESULT_OK, data=Intent { (has extras) }}}

通过ActivityResultContract的两个泛型参数约束startActivity的参数类型以及onActivityResult返回的结果类型

ActivityResultRegistry

prepareCall内会调用ActivityResultRegistry.registerActivityResultCallback()方法

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

当然Activity也可以脱离prepareCall直接调用activityResultRegistry,如下

        // ** ↓ **val launcher: ActivityResultLauncher<Intent> = activityResultRegistry        .registerActivityResultCallback(                "activity_rq#0", // 此数字在调用时保持Autoincrement        // ** ↑ **                object : ActivityResultContract<Intent, ActivityResult>() {                    override fun createIntent(input: Intent): Intent {                        return input                    }                    override fun parseResult(resultCode: Int, intent: Intent?): ActivityResult {                        return ActivityResult(resultCode, intent)                    }                }        ) { activityResult: ActivityResult ->            Log.d("MainActivity", activityResult.toString())            //  D/MainActivity: ActivityResult{resultCode=RESULT_OK, data=Intent { (has extras) }}        }

registerActivityResultCallback() 会向持有ActivityResultRegistory的HashMap执行put操作,记录ActivityResultContract


ComponentActivity相关实现


Activity中持有ActivityResultRegistry,ActivityResultRegistry通过HashMap管理ActivityResultContract和ActivityResultCallback。HashMap的Key形式如下:

 "activity_rq#" + mNextLocalRequestCode.getAndIncrement()


还需要requestCode吗


以往,onActivityResult需要通过requestCode来识别是哪个startActivityForResult的返回,现在可以通过AutoIncrement来管理。而且当进程被杀时onSaveInstanceState会自动保存requestCode和ActivityResultRegistry的key的pair对,当onActivityResult返回rc时,可以通过对应关系找到key,然后找到ActivityResultCallback

//ActivityResultRegistry.javaprivate int registerKey(String key) {        Integer existing = mKeyToRc.get(key);        if (existing != null) {            return existing;        }        int rc = mNextRc.getAndIncrement();        bindRcKey(rc, key);        return rc;    }

Fragment相关实现


Fragment.prepareCall()的实现中,在ON_CREATE的时候,会调用getActivity().getActivityResultRegistry().registerActivityResultCallback

//Fragment.javapublic <I, O> ActivityResultLauncher<I> prepareCall(            @NonNull final ActivityResultContract<I, O> contract,            @NonNull final ActivityResultCallback<O> callback) {...        getLifecycle().addObserver(new LifecycleEventObserver() {            @Override            public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,                    @NonNull Lifecycle.Event event) {                if (Lifecycle.Event.ON_CREATE.equals(event)) {                    ref.set(getActivity()                            .getActivityResultRegistry()                  // 这里registerActivityResultCallback                            .registerActivityResultCallback(                                    key, Fragment.this, contract, callback));                }            }        });        return new ActivityResultLauncher<I>() {            @Override            public void launch(I input) {...            }        };    }

registerActivityResultCallback虽然将framgent实例注入到上级持有的HashMap,但是在ON_DESTROY的时候会进行对应的后处理,所以不必担心造成内存泄漏

//ActivityResultRegistry.javalifecycle.addObserver(new LifecycleEventObserver() {            @Override            public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,                    @NonNull Lifecycle.Event event) {                if (Lifecycle.Event.ON_DESTROY.equals(event)) {                    unregisterActivityResultCallback(key);//后处理避免leak                }            }        });

更多相关文章

  1. ARouter 源码学习之Compiler
  2. Android之intent传值的三种方法
  3. android毛玻璃背景简单实现
  4. Android(安卓)studio App开发 SQLite数据的使用
  5. Android:Date、String、Long三种日期类型之间的相互转换
  6. Android(安卓)EventLog简介
  7. Android中双击返回键退出应用实例代码
  8. Android(安卓)Glide传Context引发的非法参数异常那些小坑
  9. Android设置EditText输入类型:setInputType()方法和android:input

随机推荐

  1. Android实现页面跳转
  2. AndroidManifest中activity属性设置大全
  3. android:HttpClient请求(get、post)
  4. Android中获得SD卡中的值
  5. Android(安卓)APP无法接收开机广播
  6. OpenWrt上运行Android(安卓)OS
  7. android网站汇总
  8. Android(安卓)开发判断用户是否安装微信
  9. Android(安卓)EditText 自动获取焦点,并弹
  10. android之datepicker控件用法