Android(安卓)搭建MVP+Retrofit+RxJava网络请求框架(二)
上一篇中简单介绍了mvp的概念和retrofit的基本使用,本篇主要是将rxjava和retrofit结合起来使用,并搭建mvp+rxajva+retrofit的demo;没有rxjava和retrofit基础的,建议先去看上一篇:
Android 搭建MVP+Retrofit+RxJava网络请求框架(一)
下面我们来看一下RxJava和retrofit的结合使用,为了使Rxjava与retrofit结合,我们需要在Retrofit对象建立的时候添加一句代码:
addCallAdapterFactory(RxJava2CallAdapterFactory.create())
当然你还需要在build.gradle文件中添加如下依赖:
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
本篇中所用的是rxjava2,完整的代码如下:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.douban.com/v2/") .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create())) .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持RxJava .build();
然后我们还需要修改RetrofitService 中的代码:
public interface RetrofitService { @GET("book/search") Observable getSearchBook(@Query("q") String name, @Query("tag") String tag, @Query("start") int start, @Query("count") int count);
可以看到,在原来的RetrofitService 中我们把getSearchBook方法返回的类型Call改为了Observable,也就是被观察者。其他都没变。然后就是创建RetrofitService 实体类:
RetrofitService service = retrofit.create(RetrofitService.class);
和上面一样,创建完RetrofitService ,就可以调用里面的方法了:
Observable
其实这一步,就是创建了一个rxjava中observable,即被观察者,有了被观察者,就需要一个观察者,且订阅它:
observable.subscribeOn(Schedulers.io())//请求数据的事件发生在io线程 .observeOn(AndroidSchedulers.mainThread())//请求完成后在主线程更显UI .subscribe(new DisposableObserver() {//订阅 @Override public void onComplete() { //所有事件都完成,可以做些操作。。。 } @Override public void onError(Throwable e) { e.printStackTrace(); //请求过程中发生错误 } @Override public void onNext(Book book) {//这里的book就是我们请求接口返回的实体类 } }
在上面中我们可以看到,事件的消费在Android主线程,所以我们还要在build.gradle中添加如下依赖:
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
这样我们就引入了RxAndroid,RxAndroid其实就是对RxJava的扩展。比如上面这个Android主线程在RxJava中就没有,因此要使用的话就必须得引用RxAndroid。
实践
接下来我们就看看,在一个项目中上面三者是如何配合的。我们打开Android Studio,新建一个项目取名为MVPSample。这个demo的功能也很简单,就是点击按钮调用上面的那个测试接口,将请求下来书的信息显示在屏幕上。首先我们来看一下这个工程的目录结构:
项目结构图.png我们可以看到,在项目的包名下,我们建了主要的文件夹:bean、data、presenter,ui;分别对应不同的功能。其中app文件夹中可以建一个Application类,用于设置应用全局的一些属性,这里为了使项目更加简单就没有添加;然后,我们再来看看ui文件夹下,这个文件夹下主要放一些关于界面的东西。在里面我们又建了三个文件夹:activity、adapter、fragment,我想看名字你就清楚里面要放什么了。RetrofitHelper和APiService。RetrofitHelper主要用于Retrofit的初始化:
public class RetrofitHelper { private Context mCntext; OkHttpClient client = new OkHttpClient(); GsonConverterFactory factory = GsonConverterFactory.create(new GsonBuilder().create()); private static RetrofitHelper instance = null; private Retrofit mRetrofit = null; public static RetrofitHelper getInstance(Context context){ if (instance == null){ instance = new RetrofitHelper(context); } return instance; } private RetrofitHelper(Context mContext){ mCntext = mContext; init(); } private void init() { resetApp(); } private void resetApp() { mRetrofit = new Retrofit.Builder() .baseUrl(ApiService.BASE_URL) .client(client) .addConverterFactory(factory) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } public ApiService getServer(){ return mRetrofit.create(ApiService.class); }}
代码并不复杂,其中resetApp方法,就是前面介绍的Retrofit的创建,getServer方法就是为了获取ApiService接口类的实例化。然后定义了一个静态方法getInstance用于获取自身RetrofitHelper的实例化,并且只会实例化一次。
在正式的项目中model,view,presenter都需要根据需求创建对应的BaseView,BaseModel,BasePresenter;当前demo中只是简单创建,后再后续封装中继续完善框架。
先创建一个BookInfoContract
public interface BookInfoContract { interface IView extends BaseView { void showResult(String msg);// void onRequestPermissionSuccess();//// void onRequestPermissionSError(); } interface IBookModel { Observable getBookMsg(String name,String tag,int start,int count); }}
这是采用google官方demo的写法,将相关的view和model接口写到一个协议接口类中。方便查找和管理,每一个view,model,presenter都有对应的接口类相对应,这种写法虽然类增加了,但是便于解耦,改动和维护方便;
具体实现步骤如下:
- 创建BookInfoModel,实现接口,并重写获取数据的方法
public class BookInfoModel implements BookInfoContract.IBookModel { private ApiService mApiService; public BookInfoModel(ApiService mApiService) { this.mApiService = mApiService; } @Override public Observable getBookMsg(String name, String tag, int start, int count) { return mApiService.getSearchBooks(name, tag, start, count); }}
2.创建presenter,通过构造传入需要关联的view,并初始化model;在getMsg()方法中,通过model中
getBookMsg()方法返回的被观察者进入线程切换和事件订阅;在订阅回调中,调用view的方法对请求的结果进行处理;一般presenter持有view的引用,增加了耦合性,后面会进行优化处理
public class BookPresenter { private BookInfoContract.IView mView; private BookInfoModel bookInfoModel; private Book mBook; public BookPresenter(BookInfoContract.IView mView) { this.mView = mView; bookInfoModel = new BookInfoModel(RetrofitHelper.getInstance((Context) mView).getServer()); } //获取数据 public void getMsg(String name, String tag, int start, int count) { bookInfoModel.getBookMsg(name, tag, start, count) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Book value) { mBook = value; } @Override public void onError(Throwable e) { e.printStackTrace(); mView.showError("请求失败"); } @Override public void onComplete() { if (mView != null) { mView.showResult(mBook.toString()); } } }); }}
3.在mainActivity中实现接口 BookInfoContract.IView;通过注解初始化控件(在onDestroy中进行接触注解)并获取初始化presenter,在控件监听事件中。调用presenter的方法获取数据;
经过以上几步基本完成了mvp+rxjava+retrofit的框架搭建
项目地址:https://github.com/cruiseliang/MvpSample
更多相关文章
- setHint方法
- 十九、android中判断sim卡状态和读取联系人资料的方法
- Android(安卓)studio 快捷键大全
- Android中的界面去除标题和实现全屏的两种方法
- [Digging] android:fitsSystemWindows
- Android中post请求传递json数据给服务端
- Android(安卓)Scroller的用法详解并完成ListView侧滑菜单
- Android(安卓)Studio中使用开源库volley进行网络访问简单示例
- Android(安卓)Studio中获取SHA1或MD5的方法