在 Android 中从 View-based Activity 传递数据到 Compose Activity
在 Android 应用中,从传统的基于 View 的 Activity 向基于 Jetpack Compose 的 Activity 传递数据有几种常见方法。以下是几种实现方式:
方法一:使用 Intent 传递数据
这是最简单直接的方式,适用于传递简单数据。
在 View Activity 中发送数据:
// ViewBasedActivity.kt
val intent = Intent(this, ComposeActivity::class.java).apply {
putExtra("key_string", "Hello Compose")
putExtra("key_int", 123)
putExtra("key_parcelable", myParcelableObject)
}
startActivity(intent)
在 Compose Activity 中接收数据:
// ComposeActivity.kt
class ComposeActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val stringValue = intent?.getStringExtra("key_string") ?: ""
val intValue = intent?.getIntExtra("key_int", 0) ?: 0
val parcelableValue = intent?.getParcelableExtra<MyParcelable>("key_parcelable")
setContent {
MyAppTheme {
// 在 Compose 中使用这些值
Greeting(stringValue, intValue, parcelableValue)
}
}
}
}
@Composable
fun Greeting(text: String, number: Int, data: MyParcelable?) {
// 你的 Compose UI
}
方法二:使用 ViewModel 共享数据
如果两个 Activity 需要共享更复杂的状态,可以使用共享 ViewModel。
1. 创建共享 ViewModel
class SharedViewModel : ViewModel() {
private val _sharedData = MutableStateFlow<MyData?>(null)
val sharedData: StateFlow<MyData?> = _sharedData.asStateFlow()
fun setSharedData(data: MyData) {
_sharedData.value = data
}
}
2. 在 View Activity 中设置数据
// ViewBasedActivity.kt
val viewModel: SharedViewModel by viewModels()
viewModel.setSharedData(MyData(...))
val intent = Intent(this, ComposeActivity::class.java)
startActivity(intent)
3. 在 Compose Activity 中获取数据
// ComposeActivity.kt
class ComposeActivity : ComponentActivity() {
private val viewModel: SharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val data by viewModel.sharedData.collectAsState()
MyAppTheme {
if (data != null) {
DataDisplayScreen(data!!)
} else {
LoadingScreen()
}
}
}
}
}
方法三:使用持久化存储(Room/SharedPreferences)
对于需要持久化的数据:
1. 在 View Activity 中保存数据
// 使用 SharedPreferences
val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
with(sharedPref.edit()) {
putString("key_data", "value")
apply()
}
// 或者使用 Room 数据库
myDatabase.dao().insertData(myData)
2. 在 Compose Activity 中读取数据
// ComposeActivity.kt
class ComposeActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
val data = sharedPref.getString("key_data", "")
// 或者从 Room 查询
val dbData by myDatabase.dao().getData().collectAsState(initial = emptyList())
setContent {
MyAppTheme {
DataScreen(data, dbData)
}
}
}
}
方法四:使用全局单例(谨慎使用)
对于简单的应用,可以使用全局对象:
object DataHolder {
var sharedData: MyData? = null
}
// 在 View Activity 中
DataHolder.sharedData = MyData(...)
// 在 Compose Activity 中
val data = DataHolder.sharedData
最佳实践建议
- 简单数据:使用 Intent 传递
- 复杂数据:使用 ViewModel 或持久化存储
- 避免全局状态:除非必要,尽量避免使用全局单例
- 类型安全:考虑使用
kotlinx.serialization
或 Gson 转换复杂对象为 JSON 字符串传递