安卓开发返回数据
- 行业动态
- 2025-04-22
- 2
安卓开发中返回数据的常见方式
Intent传递数据
适用场景:Activity之间传递简单数据(基本类型、Parcelable对象)
示例代码:
// 发送方 val intent = Intent(this, TargetActivity::class.java) intent.putExtra("key", "value") // 基本类型 intent.putExtra("user", user) // Parcelable对象 startActivity(intent) // 接收方 val value = intent.getStringExtra("key") val user = intent.getParcelableExtra<User>("user")
注意事项:
- 基本类型需使用对应的
putExtra
方法(如putString
,putInt
) - 自定义对象需实现
Parcelable
接口 - 数据量受限(Intent大小约1MB)
- 基本类型需使用对应的
onActivityResult与startActivityForResult
适用场景:启动新Activity并获取返回结果
示例代码:
// 发送方 val intent = Intent(this, EditActivity::class.java) startActivityForResult(intent, REQUEST_CODE) // 接收方(EditActivity) setResult(Activity.RESULT_OK, Intent().apply { putExtra("result", "data") }) finish() // 发送方重写onActivityResult override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) { val result = data?.getStringExtra("result") } }
缺点:
- 仅支持Activity间通信
- API 30后被弃用,推荐使用
registerForActivityResult
ViewModel共享数据
适用场景:同一进程内多Activity/Fragment共享数据
示例代码:
// 定义ViewModel class SharedViewModel : ViewModel() { val data = MutableLiveData<String>() } // ActivityA val viewModel = ViewModelProvider(this).get(SharedViewModel::class.java) viewModel.data.value = "Hello" // ActivityB val viewModel = ViewModelProvider(this).get(SharedViewModel::class.java) viewModel.data.observe(this) { value -> // 接收数据 }
优点:
- 生命周期安全
- 支持LiveData实时更新
LiveData总线(事件式通信)
适用场景:全局事件通知(如网络请求完成)
示例代码:
// 定义Bus object EventBus : LiveData<Event>() { override fun postValue(value: Event) { super.postValue(value) } } // 发送事件 EventBus.postValue(Event.DataLoaded("data")) // 观察事件 EventBus.observe(this) { event -> when (event) { is Event.DataLoaded -> showData(event.data) } }
注意:需处理内存泄漏(使用LifecycleOwner)
回调接口(Listener模式)
适用场景:异步操作回调(如网络请求、数据库操作)
示例代码:
// 定义接口 interface DataCallback { fun onSuccess(data: String) fun onFailure(error: Exception) } // 调用方 loadData(object : DataCallback { override fun onSuccess(data: String) { / 处理数据 / } override fun onFailure(error: Exception) { / 处理错误 / } })
缺点:强耦合,难以扩展多观察者
广播(BroadcastReceiver)
适用场景:跨组件通信(如Service通知Activity)
示例代码:
// 发送广播 val intent = Intent("com.example.DATA_UPDATED") intent.putExtra("data", "newData") sendBroadcast(intent) // 注册接收器 val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val data = intent.getStringExtra("data") } } registerReceiver(receiver, IntentFilter("com.example.DATA_UPDATED"))
注意:静态注册需在Manifest声明,动态注册需及时注销
方法对比表
方法 | 数据类型限制 | 生命周期安全 | 跨组件支持 | 性能开销 |
---|---|---|---|---|
Intent传值 | 基本类型/小对象 | 否 | 是 | 低 |
onActivityResult | 基本类型/小对象 | 否 | 否 | 中 |
ViewModel | 无限制 | 是 | 否 | 低 |
LiveData总线 | 无限制 | 是 | 是 | 中 |
回调接口 | 无限制 | 否 | 否 | 低 |
广播 | 基本类型/小对象 | 否 | 是 | 高 |
相关问题与解答
Q1:如何返回大数据对象(如Bitmap)?
A:
- 方案1:通过
Singleton
或Application
全局存储对象引用 - 方案2:使用
ParcelFileDescriptor
传递文件描述符 - 方案3:将数据保存至缓存目录,传递文件路径
// 示例:传递文件路径 val file = File(cacheDir, "temp.png") file.outputStream().use { outputStream -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) } intent.putExtra("filePath", file.absolutePath)
Q2:如何在Fragment之间安全传递数据?
A:
- 方案1:通过
Bundle
在setArguments
中传递(适用于同Activity的Fragment) - 方案2:使用共享
ViewModel
(需所属同一NavController
或Activity
) - 方案3:通过
findNavController().previousBackStackEntry
访问目标Fragment的参数// 使用SafeArgs插件生成类型安全参数传递 val directions = FirstFragmentDirections.actionFirstToSecond(arg1 = "data") findNavController().navigate(directions)