什么是MVVM
MVVM(Model-View-ViewModel)是Android官方推荐的架构模式,相较于MVC和MVP,它通过数据绑定实现了更彻底的界面与逻辑分离。

组件 | 职责 | 对应Android实现 |
---|
Model | 数据获取与业务逻辑 | Repository, DataSource |
View | UI展示与用户交互 | Activity/Fragment, XML |
ViewModel | 界面状态管理 | ViewModel, LiveData |
什么是Rxjava
RxJava 是响应式编程在 Android 上的核心实现
observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
操作符 | 作用阶段 | 多次调用效果 |
---|
subscribeOn | 数据发射阶段 | 只有第一次生效 |
observeOn | 数据接收阶段 | 每次都会改变线程 |
线程是怎么切换的
- 通过
Scheduler.Worker
调度任务
observeOn
使用队列+线程切换

主要调度器实现
调度器类型 | 内部机制 | 适用场景 |
---|
Schedulers.io() | 动态扩容线程池(CachedThreadPool) | 网络/文件IO操作 |
Schedulers.computation() | 固定大小线程池(CPU核心数) | 计算密集型任务 |
AndroidSchedulers.mainThread() | Handler(Looper.getMainLooper()) | Android UI更新 |
map 和 flatmap
特性 | map | flatMap |
---|
转换关系 | 1:1 同步转换 | 1:N 异步转换 |
返回值要求 | 直接返回结果对象 | 返回新的Observable |
线程安全 | 默认在调用线程执行 | 可指定子Observable的调度线程 |
顺序保证 | 严格保持源顺序 | 结果顺序可能变化(除非用concatMap) |
典型应用场景 | 简单数据类型转换 | 嵌套异步操作 |
Observable.just("apple", "banana")
.map(String::toUpperCase)
.subscribe(System.out::println);
Observable.just("user1", "user2")
.flatMap(username ->
queryUserDetail(username).subscribeOn(Schedulers.io())
.subscribe(System.out::println);
doOnNext 非侵入式观察:不影响原始数据流
observable
.doOnNext(item -> System.out.println("收到数据: " + item))
.map(...)
.subscribe(...);
背压 (Backpressure)是响应式编程中处理生产者与消费者速度不匹配的核心机制
Flowable.range(1, 1000)
.subscribe(new Subscriber<Integer>() {
private Subscription subscription;
private int count = 0;
@Override
public void onSubscribe(Subscription s) {
this.subscription = s;
s.request(10);
}
@Override
public void onNext(Integer item) {
process(item);
if (++count % 5 == 0) {
subscription.request(5);
}
}
@Override public void onError(Throwable t) { t.printStackTrace(); }
@Override public void onComplete() { System.out.println("完成"); }
});
界面防抖
view.clicks()
.toFlowable(BackpressureStrategy.LATEST)
.onBackpressureDrop { showToast("操作过快") }
.observeOn(AndroidSchedulers.mainThread())
.subscribe { updateUI() }
searchEditText.textChanges() // 使用RxBinding
.debounce(500, TimeUnit.MILLISECONDS) // 停止输入500ms后触发
.filter { it.isNotBlank() }
.switchMap { query ->
api.search(query).onErrorReturn { emptyList() }
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe { results ->
showSearchResults(results)
}
wanandroid 注册登录MVVM 实践
github.com/luyuqin0115…
build.gradle 配置
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
implementation("io.reactivex.rxjava3:rxjava:3.1.8")
implementation("io.reactivex.rxjava3:rxandroid:3.0.2")
implementation("com.google.code.gson:gson:2.10.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
implementation("androidx.navigation:navigation-compose:2.7.6")
implementation("androidx.compose.material:material-icons-extended:1.5.4")