为了有效使用Android的ActivityResult API,遵循以下最佳实践可提升代码质量和维护性:
1. 初始化与注册位置
- 在
onCreate中注册:在Activity或Fragment的onCreate方法中注册ActivityResultLauncher,确保生命周期安全,避免重复注册。lateinit var imagePickerLauncher: ActivityResultLauncher<String> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) imagePickerLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri -> uri?.let { handleImage(it) } } }
2. 使用预定义Contract
- 利用系统提供的Contracts:如
GetContent、RequestPermission、TakePicture等,简化常见操作。val requestPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted -> if (isGranted) showCamera() else showPermissionDenied() }
3. 自定义Contract封装逻辑
- 内聚数据传递与解析:自定义Contract处理特定业务,如启动编辑页面并返回结果。
class EditContract : ActivityResultContract<String, String?>() { override fun createIntent(context: Context, input: String): Intent = Intent(context, EditActivity::class.java).apply { putExtra("INITIAL_TEXT", input) } override fun parseResult(resultCode: Int, intent: Intent?): String? = if (resultCode == Activity.RESULT_OK) intent?.getStringExtra("RESULT_TEXT") else null } // 注册使用 val editLauncher = registerForActivityResult(EditContract()) { result -> result?.let { updateTextView(it) } }
4. 处理结果与异常情况
- 检查结果有效性:处理用户取消或数据缺失情况,避免崩溃。
val startForResult = registerForActivityResult(StartActivityForResult()) { result -> when (result.resultCode) { RESULT_OK -> parseData(result.data) RESULT_CANCELED -> showUserCanceledToast() else -> handleUnexpectedResult() } }
5. 线程与UI安全
- 主线程回调:直接在回调中更新UI,避免耗时操作。若需处理数据,使用协程或后台线程。
imagePickerLauncher = registerForActivityResult(GetContent()) { uri -> uri?.let { lifecycleScope.launch { val bitmap = withContext(Dispatchers.IO) { loadBitmap(it) } imageView.setImageBitmap(bitmap) } } }
6. 代码组织与可读性
- 逻辑分组:按功能模块组织launcher,避免
onCreate臃肿。使用Kotlin扩展或单独类管理。// 扩展函数分组 fun MainActivity.registerLaunchers() { imagePickerLauncher = registerForActivityResult(GetContent()) { /* ... */ } editLauncher = registerForActivityResult(EditContract()) { /* ... */ } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) registerLaunchers() }
7. 内存与生命周期管理
- 避免泄露:回调中避免直接引用View,使用弱引用或检查生命周期状态。
imagePickerLauncher = registerForActivityResult(GetContent()) { uri -> if (isDestroyed) return@registerForActivityResult // 检查Activity状态 uri?.let { loadImage(it) } }
8. 测试与调试
- 模拟结果场景:单元测试中验证各种结果码和数据组合,确保健壮性。
@Test fun testEditContract() { val contract = EditContract() val intent = contract.createIntent(context, "Test") val result = contract.parseResult(Activity.RESULT_OK, Intent().apply { putExtra("RESULT_TEXT", "New Text") }) assertEquals("New Text", result) }
9. 处理配置变更
- 自动重建Launcher:系统自动处理launcher的重建,无需额外代码,但需测试旋转后的行为。
10. 文档与注释
- 明确合约职责:为自定义Contract添加文档,说明输入输出及使用场景。
/** * 启动EditActivity并返回编辑后的文本 * @param String 初始文本 * @return String? 编辑后的文本(RESULT_OK时非空) */ class EditContract : ActivityResultContract<String, String?>() { ... }
总结
通过合理利用ActivityResult API,将请求与结果处理逻辑集中,提升代码清晰度。结合预定义和自定义Contract,适应多样化场景,同时注意生命周期和异常处理,确保应用稳健高效。