安卓开发:从新技术应用到清洁架构的演变
立即解锁
发布时间: 2025-09-14 01:11:56 阅读量: 1 订阅数: 3 AIGC 

### 安卓开发:从新技术应用到清洁架构的演变
#### 1. 新技术的引入
在安卓开发中,新的库和框架不断涌现,极大地改变了开发方式。
- **持久化库**:
- **Room**:开发者无需再直接与 SQLite 框架交互,避免了大量用于定义表和查询的样板代码。开发者可以专注于创建自己的模型,并为查询、删除、更新等操作提供抽象,Room 会处理实际的实现。
- **DataStore**:类似于 Room 对 SQLite 的作用,DataStore 用于 SharedPreferences。当需要以键值对的形式存储数据时使用,提供了安全类型数据和无类型安全数据两种存储选项。
- **Repository 模式**:随着上述持久化库的引入,Repository 模式被广泛采用。该模式的核心思想是创建一个类,用于与应用中的所有数据源进行交互。例如,当需要从后端获取数据并本地存储,以便用户离线查看时,Repository 负责从网络类获取数据,并使用持久化类进行存储,它位于本地和远程类与需要访问该数据的类之间。
- **视图绑定和数据绑定**:
- **视图绑定**:为 XML 布局文件中定义的每个视图生成引用,解决了过去可能出现的问题。例如,当从 XML 文件中删除一个视图时,由于另一个文件中有同名视图,应用仍可能运行,但 findViewById 函数会返回 null 导致崩溃。使用视图绑定,在编译时就能明确视图层次结构中包含和不包含的视图。
- **数据绑定**:允许将视图绑定到数据源。例如,可以将 XML 文件中的 TextView 直接绑定到源代码中的字段。这种方法与 MVVM 模式配合良好,ViewModel 更新 XML 中视图绑定的某些字段,从而更新视图显示,而无需与 Activity 交互。
- **协程和流**:
- **协程**:是 Kotlin 语言的一个特性,以非常简化的方式异步执行数据。开发者不再需要创建线程或使用已弃用的 AsyncTasks 来管理并发,这些操作由底层自动处理。协程不绑定到特定线程,可以暂停和恢复。
- **流**:是协程的扩展,允许有多个数据发射,类似于 RxJava,提供类似的好处。
#### 2. Jetpack Compose
Jetpack Compose 允许开发者直接在 Kotlin 中通过可组合函数构建 UI,无需使用 XML 文件,减少了构建 UI 所需的代码量。它与其他安卓架构组件库兼容,便于集成到应用中。以下是一个简单的示例:
```kotlin
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ExampleTheme {
Surface {
ExampleScreen()
}
}
}
}
}
@Composable
fun ExampleScreen() {
Column(modifier = Modifier.padding(16.dp)) {
TextField(
value = "",
onValueChange = {
// Handle text change
},
label = { Text("Input") }
)
Text(text = "Example text")
Button(onClick = {
// Handle button click
}) {
Text(text = "Button")
}
}
}
```
#### 3. 代码迁移示例
将旧的示例代码迁移到 Kotlin,并使用 Retrofit、Moshi、Hilt 等库进行网络、JSON 序列化和依赖注入,同时使用 ViewModel、LiveData 和 Compose 处理 UI 层。
- **ConcreteData 类**:
```kotlin
@JsonClass(generateAdapter = true)
data class ConcreteData(
@Json(name = "field1") val field1: String,
@Json(name = "field1") val field2: String
)
```
- **ConcreteDataService 接口**:
```kotlin
interface ConcreteDataService {
@GET("/path")
suspend fun getConcreteData(): ConcreteData
}
```
- **ConcreteDataRepository 类**:
```kotlin
class ConcreteDataRepository @Inject constructor(private val concreteDataService: ConcreteDataService) {
fun getConcreteData(): Flow<ConcreteData> {
return flow {
val fooList = concreteDataService.getConcreteData()
emit(fooList)
}.flowOn(Dispatchers.IO)
}
}
```
- **MainViewModel 类**:
```kotlin
@HiltViewModel
class MainViewModel @Inject constructor(private val concreteDataRepository: ConcreteDataRepository) : ViewModel() {
private val _concreteData = MutableLiveData<ConcreteData>()
val concreteData: LiveData<ConcreteData> get() = _concreteData
fun loadConcreteData() {
viewModelScope.launch {
concreteDataRepository.getConcreteData().collect { data ->
_concreteData.postValue(data)
}
}
}
}
```
- **MainActivity 类**:
```kotlin
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Screen()
}
}
}
@Composable
fun Screen(mainViewModel: MainViewModel = viewModel()){
mainViewModel.loadConcreteData()
UpdateText()
}
@Composable
fun UpdateText(mainViewModel: MainViewModel = viewModel()) {
val concreteData by mainViewModel.concreteData.observeAsState(ConcreteData("test", "test"))
MessageView(text = concreteData.field1)
}
@Composable
fun MessageView(text: String) {
Text(text = text)
}
```
- **Hilt 模块**:
```kotlin
@Module
@InstallIn(SingletonComponent::class)
class ApplicationModule {
@Singleton
@Provides
fun provideHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.readTimeout(15, TimeUnit.SECONDS)
.connectTimeout(15, TimeUnit.SECONDS)
.build()
}
@Singleton
@Provides
fun provideConverterFactory(): MoshiConverterFactory = MoshiConverterFactory.create()
@Singleton
@Provides
fun p
```
0
0
复制全文
相关推荐









