本篇基于DeepSeek 搜索结果修改。
在传统的Android开发中,我们经常会遇到以下痛点:
// 传统方式处理数据变化
button.setOnClickListener {
// 触发网络请求
fetchDataFromNetwork { result ->
// 更新UI
textView.text = result
// 如果数据依赖其他状态,需要手动管理
if (result.isNotEmpty()) {
recyclerView.visibility = View.VISIBLE
} else {
recyclerView.visibility = View.GONE
}
}
}
这种方式存在以下问题:
数据流是响应式编程的核心,它可以是:
观察者模式由以下部分组成:
// 简化版观察者模式实现
class Observable<T> {
private val observers = mutableListOf<Observer<T>>()
fun subscribe(observer: Observer<T>) {
observers.add(observer)
}
fun emit(value: T) {
observers.forEach { it.onNext(value) }
}
}
interface Observer<T> {
fun onNext(value: T)
fun onError(error: Throwable)
fun onComplete()
}
操作符用于转换、过滤和组合数据流:
LiveData是Android官方提供的可观察数据持有者类:
// 创建LiveData
val liveData = MutableLiveData<String>()
// 观察LiveData
liveData.observe(this) { value ->
// 数据变化时更新UI
textView.text = value
}
// 更新LiveData
liveData.value = "New Value"
LiveData通常与ViewModel结合使用:
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> = _data
fun loadData() {
// 模拟数据加载
viewModelScope.launch {
delay(1000)
_data.value = "Loaded Data"
}
}
}
RxJava使用Observable和Observer处理数据流:
// 创建Observable
Observable<String> observable = Observable.just("Hello", "RxJava", "World");
// 创建Observer
Observer<String> observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
// 订阅时调用
}
@Override
public void onNext(String s) {
// 接收到数据时调用
Log.d("RxJava", s);
}
@Override
public void onError(Throwable e) {
// 发生错误时调用
}
@Override
public void onComplete() {
// 完成时调用
}
};
// 订阅
observable.subscribe(observer);
使用操作符处理复杂数据流:
Observable.just("apple", "banana", "cherry")
.map(fruit -> fruit.toUpperCase())
.filter(fruit -> fruit.startsWith("B"))
.subscribe(fruit -> {
Log.d("RxJava", "Filtered: " + fruit);
});
Flow是Kotlin协程中的响应式编程库:
// 创建Flow
fun numbers(): Flow<Int> = flow {
for (i in 1..3) {
delay(100)
emit(i)
}
}
// 收集Flow
viewModelScope.launch {
numbers()
.map { it * it }
.collect { value ->
Log.d("Flow", "Received: $value")
}
}
使用Flow处理网络请求:
suspend fun fetchData(): Flow<Data> = flow {
// 模拟网络请求
val response = apiService.getData()
emit(response)
}
editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
// 每次文本变化都触发搜索
performSearch(s.toString())
}
override fun afterTextChanged(s: Editable?) {}
})
private fun performSearch(query: String) {
// 执行搜索
}
RxTextView.textChanges(editText)
.debounce(300, TimeUnit.MILLISECONDS)
.filter(text -> text.length() > 2)
.switchMap(query -> searchApi.search(query.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
)
.subscribe(results -> {
// 更新UI
});
editText.textChanges()
.debounce(300)
.filter { it.length > 2 }
.mapLatest { query ->
repository.search(query.toString())
}
.flowOn(Dispatchers.IO)
.onEach { results ->
// 更新UI
}
.launchIn(lifecycleScope)
fun getUsers(): Flow<List<User>> = flow {
// 先发射本地数据
emit(localDataSource.getUsers())
// 再发射远程数据
val remoteUsers = remoteDataSource.getUsers()
localDataSource.saveUsers(remoteUsers)
emit(remoteUsers)
}
可以看出,Android 的响应式编程范式主要是由观察者模式结合响应式流来实现的。观察者模式作为核心架构,构建起数据生产者与消费者之间的订阅关系,使得数据变化能够及时被关注;响应式流则负责承载数据的流动与处理,通过操作符对数据进行转换、过滤等操作,实现复杂业务逻辑的编排。