Android 搭建MVP+Retrofit+RxJava網(wǎng)絡(luò)請求框架(二)

上一篇中簡單介紹了mvp的概念和retrofit的基本使用,本篇主要是將rxjava和retrofit結(jié)合起來使用,并搭建mvp+rxajva+retrofit的demo;沒有rxjava和retrofit基礎(chǔ)的,建議先去看上一篇:
Android 搭建MVP+Retrofit+RxJava網(wǎng)絡(luò)請求框架(一)

下面我們來看一下RxJava和retrofit的結(jié)合使用,為了使Rxjava與retrofit結(jié)合,我們需要在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<Book> getSearchBook(@Query("q") String name,
                                    @Query("tag") String tag, @Query("start") int start,
                                    @Query("count") int count);

可以看到,在原來的RetrofitService 中我們把getSearchBook方法返回的類型Call改為了Observable,也就是被觀察者。其他都沒變。然后就是創(chuàng)建RetrofitService 實體類:

RetrofitService service = retrofit.create(RetrofitService.class);
和上面一樣,創(chuàng)建完RetrofitService ,就可以調(diào)用里面的方法了:

Observable<Book> observable = service.getSearchBook("人間失格", null, 0, 1);
其實這一步,就是創(chuàng)建了一個rxjava中observable,即被觀察者,有了被觀察者,就需要一個觀察者,且訂閱它:

observable.subscribeOn(Schedulers.io())//請求數(shù)據(jù)的事件發(fā)生在io線程
          .observeOn(AndroidSchedulers.mainThread())//請求完成后在主線程更顯UI
          .subscribe(new DisposableObserver<Book>() {//訂閱
              @Override
              public void onComplete() {
                  //所有事件都完成,可以做些操作。。。
              }
              @Override
              public void onError(Throwable e) {
                  e.printStackTrace(); //請求過程中發(fā)生錯誤
              }
              @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的功能也很簡單,就是點擊按鈕調(diào)用上面的那個測試接口,將請求下來書的信息顯示在屏幕上。首先我們來看一下這個工程的目錄結(jié)構(gòu):

項目結(jié)構(gòu)圖.png

我們可以看到,在項目的包名下,我們建了主要的文件夾:bean、data、presenter,ui;分別對應不同的功能。其中app文件夾中可以建一個Application類,用于設(shè)置應用全局的一些屬性,這里為了使項目更加簡單就沒有添加;然后,我們再來看看ui文件夾下,這個文件夾下主要放一些關(guān)于界面的東西。在里面我們又建了三個文件夾: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的創(chuàng)建,getServer方法就是為了獲取ApiService接口類的實例化。然后定義了一個靜態(tài)方法getInstance用于獲取自身RetrofitHelper的實例化,并且只會實例化一次。

在正式的項目中model,view,presenter都需要根據(jù)需求創(chuàng)建對應的BaseView,BaseModel,BasePresenter;當前demo中只是簡單創(chuàng)建,后再后續(xù)封裝中繼續(xù)完善框架。
先創(chuàng)建一個BookInfoContract

public interface BookInfoContract {
    interface IView extends BaseView {

        void showResult(String  msg);

//        void onRequestPermissionSuccess();
//
//        void onRequestPermissionSError();
    }

     interface IBookModel {

        Observable<Book> getBookMsg(String name,String tag,int start,int count);

    }

}

這是采用google官方demo的寫法,將相關(guān)的view和model接口寫到一個協(xié)議接口類中。方便查找和管理,每一個view,model,presenter都有對應的接口類相對應,這種寫法雖然類增加了,但是便于解耦,改動和維護方便;
具體實現(xiàn)步驟如下:

  1. 創(chuàng)建BookInfoModel,實現(xiàn)接口,并重寫獲取數(shù)據(jù)的方法
public class BookInfoModel implements BookInfoContract.IBookModel {

    private ApiService mApiService;

    public BookInfoModel(ApiService mApiService) {
        this.mApiService = mApiService;
    }

    @Override
    public Observable<Book> getBookMsg(String name, String tag, int start, int count) {
        return mApiService.getSearchBooks(name, tag, start, count);
    }
}

2.創(chuàng)建presenter,通過構(gòu)造傳入需要關(guān)聯(lián)的view,并初始化model;在getMsg()方法中,通過model中
getBookMsg()方法返回的被觀察者進入線程切換和事件訂閱;在訂閱回調(diào)中,調(diào)用view的方法對請求的結(jié)果進行處理;一般presenter持有view的引用,增加了耦合性,后面會進行優(yōu)化處理

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());
    }

    //獲取數(shù)據(jù)
    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<Book>() {
                    @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中實現(xiàn)接口 BookInfoContract.IView;通過注解初始化控件(在onDestroy中進行接觸注解)并獲取初始化presenter,在控件監(jiān)聽事件中。調(diào)用presenter的方法獲取數(shù)據(jù);

經(jīng)過以上幾步基本完成了mvp+rxjava+retrofit的框架搭建
項目地址:https://github.com/cruiseliang/MvpSample

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容