通过对 RxAndroid、Retrofit 和 OkHttp 的学习,用它们整合搭建一个基于 MVVM 的项目。
使用 Android Jetpack 组件 Databinding、ViewModel、LiveData、Lifecycle
通过本篇 Blog 可以学习到如何利用这些框架整合搭建一个项目。
本篇 Blog 所用源码 Github 地址:MVVM Demo
下面开始进入正题,本篇以获取公众号列表数据展示为例。文章目录按照 Demo 项目从数据到业务逻辑处理最后到界面展示。
准备工作
-
添加依赖
依赖的版本一定要匹配,不然会出现一些乱七八糟的问题。细节可以看我之前的 Blog 集成错误因为在 Retrofit2 中使用了 JDK8 的新特性,所以除了依赖,还要添加支持。
// Support new features of JDK1.8
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// Android JetPack,也可以分别添加使用具体的某个组件的依赖
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
// okHttp 3.14
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
// Retrofit 2.9
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// Convert Google Json(Convert the result to Model)
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
// Retrofit CallAdapter convert to RxJava
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
// RxAndroid 3.0
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
复制代码
- 声明权限
<uses-permission android:name="android.permission.INTERNET" />
复制代码
-
项目目录
建好目录后,就可以开工了。
请求数据
该实例以玩 Android 为数据源。
我们使用 OkHttp 实现网络请求,Retrofit 以接口的形式回调,通过 RxAndroid 更好的处理业务和展示工作。
- 创建接口
首先,创建公众号列表数据的接口 MpService.java,然后声明这个 geListData()
@GET("wxarticle/chapters/json")
Observable<BaseData<List<MpBean>>> getListData();
// 也可以使用GET或者POST来请求
/**
* Request Buyer Data for GET
* @param id dateId
* @return buyer data
*/
@GET("buyer/date/get")
Observable<BaseData<Map<String, Map<String, String>>>> getBuyerData(@Query("dateId") String id);
/**
* Request Buyer Data for POST
* @param dateId dateId
* @return buyer data
*/
@FormUrlEncoded
@POST("buyer/date/get")
Observable<BaseData<Map<String, Map<String, String>>>> postBuyerData(@Field("dateId") String dateId);
复制代码
- 代理对象
有了接口并不能直接使用,我们需要获取代理对象,在 MainModel.java 中通过 Retrofit 的 create 方法传入接口就可以了。当然,我们要先创建一个 Retrofit 对象
private Retrofit retrofit = new Retrofit.Builder().
baseUrl(HttpConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.build();
// 获取代理对象
retrofit.create(MpSerivce.class)
复制代码
- 建立订阅
我们的接口返回的是一个 Observable,那么我们就需要传入一个 Observer,然后建立订阅关系。
其中,getListData 是用来获取 Observable,subscribe 建立订阅关系,并指定工作线程。
/**
* get the proxy object of MpService
* get the observable of proxy object
* build a subscription relationship
* @param observer observer
*/
public void subscribe(Observer<BaseData<List<MpBean>>> observer) {
retrofit.create(MpSerivce.class).getListData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
复制代码
处理逻辑
创建 ViewModel、Adapter 及 Adapter 布局文件。
- 创建 Observer 响应事件
Observer<BaseData<List<MpBean>>> observer = new Observer<BaseData<List<MpBean>>>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
}
@Override
public void onNext(@io.reactivex.rxjava3.annotations.NonNull BaseData<List<MpBean>> listBaseData) {
if (listBaseData.getErrorCode() == 0) {
mainAdapter.setList(listBaseData.getData());
}
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
// error
}
@Override
public void onComplete() {
Toast.makeText(mContext, "get data completed.", Toast.LENGTH_SHORT).show();
}
};
// build subscription relationship
mainModel.subscribe(observer);
复制代码
- 创建 Adapter 处理
@NonNull
@Override
public MainAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
AdapterMainBinding adapterMainBinding = DataBindingUtil.inflate(inflater, R.layout.adapter_main, parent, false);
return new ViewHolder(adapterMainBinding);
}
@Override
public void onBindViewHolder(@NonNull MainAdapter.ViewHolder holder, int position) {
// 不再需要单独对控件赋值,通过DataBinding数据绑定
MpBean bean = list.get(position);
if (bean != null) {
holder.binding.setMp(bean);
}
}
class ViewHolder extends RecyclerView.ViewHolder {
private AdapterMainBinding binding;
// 不需要使用itemView进行findViewById,而是直接使用DataBinding
ViewHolder(@NonNull AdapterMainBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
复制代码
界面展示
在 MainActivity 中通过 View Model 调用即可。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
mainViewModel.getMpData();
mainBinding.rvMain.setAdapter(mainViewModel.mainAdapter);
}
复制代码
效果展示
补充
如果想要使用 LiveData、Lifecycle,我们可以按照下面的三个步骤进行。
- 创建 LiveData
显然,我们需要在 ViewModel 中创建 LiveData
public class NameViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> currentName;
public MutableLiveData<String> getCurrentName() {
if (currentName == null) {
currentName = new MutableLiveData<String>();
}
return currentName;
}
// Rest of the ViewModel...
}
复制代码
- 观察 LiveData
通过创建一个观察者来观察 LiveData 的变化
public class NameActivity extends AppCompatActivity {
private NameViewModel model;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Other code to setup the activity...
// Get the ViewModel.
model = new ViewModelProvider(this).get(NameViewModel.class);
// 下面是核心代码
// Create the observer which updates the UI.
final Observer<String> nameObserver = new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI, in this case, a TextView.
nameTextView.setText(newName);
}
};
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
model.getCurrentName().observe(this, nameObserver);
}
}
复制代码
- 更新 LiveData
然后我们就可以更新 LiveData 了。有 setValue 和 postValue 两种方式,区别在于 setValue 在主线程中使用,而 postValue 在工作线程中更新。
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String anotherName = "John Doe";
// 下面的代码用来更新LiveData
model.getCurrentName().setValue(anotherName);
}
});
复制代码
以上就是关于 LiveData 和 Lifecycle 的使用,其实在 Android 开发者平台上有更详细的官方文档说明。可以深入研究下。
结束
到这儿本篇 Blog 就基本结束了。如果有错误或者不明白的地方可以留言或者查看本文所用代码。
Github 地址:MVVM Demo
感觉对你有帮助的话,可以随手 Star,谢谢。
本篇参考 Blog 如下
Retrofit + RxAndroid 常见 Bug
给 Android 开发者的 RxJava 详解
你真的会用 Retrofit 吗?
Android MVVM 搭建项目基本版
Android 开发者官方