如何在RecyclerView Adapter中处理已废弃的onActivityResult回调?
实现方案
核心逻辑是将Intent启动的操作通过回调桥接给宿主Activity处理,registerForActivityResult 必须在宿主组件(Activity/Fragment)的生命周期STARTED之前完成注册,不能放到Adapter中动态注册,避免内存泄漏和注册时机异常。
步骤1:在Adapter中定义回调接口
首先给Adapter新增回调接口,用来把触发文件保存的事件通知给宿主Activity:
class YourAdapter( private val dataList: List<YourData>, // 回调实例从构造函数传入 private val onOperationListener: OnOperationListener ) : RecyclerView.Adapter<YourAdapter.ViewHolder>() { // 自定义回调接口,有多种操作可以加多个方法或者加type参数区分 interface OnOperationListener { // 对应之前的保存文件请求 fun onSaveFileRequest() // 如果有其他类型的请求,比如选图片,再加对应方法即可 // fun onPickImageRequest() } // 原Adapter中触发startActivityForResult的位置,改成调用回调 inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(data: YourData) { // 比如点击保存按钮时触发 itemView.saveBtn.setOnClickListener { onOperationListener.onSaveFileRequest() } } } // ... 其余Adapter原有逻辑不变 }
步骤2:宿主Activity实现回调接口
Activity实现刚才定义的接口,在回调方法里直接调用你已经写好的saveIntent launcher启动Intent即可,原有回调逻辑完全不需要修改:
class YourActivity : AppCompatActivity(), YourAdapter.OnOperationListener { // 你已经写好的launcher注册逻辑不变 val saveIntent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { result.data?.data?.let { uri -> saveData(uri) } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化Adapter的时候把当前Activity作为回调实例传入 val adapter = YourAdapter(数据列表, this) recyclerView.adapter = adapter } // 实现接口的保存请求方法 override fun onSaveFileRequest() { // 启动Intent的逻辑移到这里 Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "*/*" saveIntent.launch(this) } } // ... 其余Activity原有逻辑不变 }
多请求类型适配
如果你之前有多个不同的requestCode对应不同的业务逻辑,只需要:
- 给回调接口加对应的方法,或者加个请求类型参数区分
- 在Activity中注册多个对应业务的Activity Result launcher,在对应回调里调用即可
该方案既符合新API的注册要求,也做到了Adapter和Activity的解耦,不需要在Adapter中持有Activity实例,避免内存泄漏风险。
内容的提问来源于stack exchange,提问作者J Lukas
相关产品推荐
相关产品推荐

