RxJava+Retrofit+OkHttp深入淺出-mvp(使用篇)

yangxi_001發表於2017-06-12

背景

RxJava+Retrofit+OkHttp封裝系列也基本完成了,功能無太大迭代的需要,但是最近QQ群中有兄弟問如何結合mvp使用這套框架,仔細考慮下確實現在結合mvp開發專案已經是一種大趨勢,不得不感嘆現在技術更新的真是太快了,所以決定再一次操刀講解下結合mvp使用需要注意的細節。

思路

既然是結合mvp,那就必須先了解mvp是很方聖神了,之前也出過相關的博文,就不囉嗦了。在瞭解了mvp的特效後,之前的封裝大致需要做出以下修改:

  • 剔除載入框統一處理,採用介面view層中手動顯示呼叫

  • 簡化ProgressSubscriber功能,去掉無用的content依賴,降低耦合

  • 將網路處理加入mvp框架的model層處理

思路完成了,重度使用患者估計已經完全明白了。開始我們的使用

mvp簡單使用

先簡單的來一個例子,幫對mvp不懂的同學複習下。

view介面

定義view層回撥介面

public interface Vlistener {

    void onTestNext(String msg);
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

presenter介面

定義兩個介面,一個使用者view層,一個用於model,確保Model層不直接操作View層;

p層提供給v層的介面

/**
 * p層提供給v層的介面
 * Created by WZG on 2016/12/26.
 */
public interface Plistener {

    /**
     * 其他方法-演示
     * @param msg
     */
    void doTest(String msg);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

mvp 中p層提供給m層使用的介面


/**
 * mvp 中p層提供給m層使用的介面
 * Created by WZG on 2016/12/26.
 */

public interface PVlistener {

    /**
     * 測試回撥
     * @param msg
     */
    void testPSuc(String msg);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

m層提供給p層的介面

/**
 * m層提供給p層的介面
 * Created by WZG on 2016/12/26.
 */

public interface Mlistener {
    /**
     * 測試介面
     * @param s
     */
    void testDo(String s);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

view層事件呼叫

view 層擁有一個presenter層的引用,觸發事件後呼叫presenter層介面處理。

  private Plistener plistener;

@OnClick(value = R.id.tv_test)
    void onTvTestClick(View view) {
        plistener.doTest("1");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

presenter層呼叫model層介面初始資料

public class P implements Plistener,PVlistener{
    private Vlistener vlistener;
    private Mlistener mlistener;

    public P(Vlistener viewListener) {
        this.vlistener = viewListener;
        mlistener =new M(this);
    }

    @Override
    public void doTest(String msg) {
        mlistener.testDo(msg);
    }

    @Override
    public void testPSuc(String msg) {
        vlistener.onTestNext(msg);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

model層處理資料,回撥給presenter, presenter回撥給view

public class M implements Mlistener{
    private PVlistener pVlistener;

    public M(PVlistener pVlistener) {
        this.pVlistener = pVlistener;
    }

    @Override
    public void testDo(String s) {
        String msg = "M" + s;
        pVlistener.testPSuc(msg);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

presenter層傳遞給view

  @Override
    public void testPSuc(String msg) {
        vlistener.onTestNext(msg);
    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

通過以上的虛擬碼,大致瞭解了mvp呼叫的執行過程,所以結合RxRetrofit使用只需要各層新增對應的介面,在model層中觸發http請求即可;

結合RxRetorift 使用

view層新增介面

public interface Vlistener {

    void onTestNext(String msg);

    void showProg();

    void dismissProg();

    void onNext(String s,String m);

    void  onError(ApiException e);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

view回撥實現

首先封裝一個簡單的BaseActivity處理公用的載入框顯示和隱藏處理

public class BaseActivity extends RxAppCompatActivity {
    //    載入框可自己定義
    protected ProgressDialog pd;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(pd==null){
            pd = new ProgressDialog(this);
            pd.setCancelable(false);
        }
    }

    protected void showP(){
        if(pd!=null&&!pd.isShowing()){
            pd.show();
        }
    }

    protected void dismissP(){
        if(pd!=null&&pd.isShowing()){
            pd.dismiss();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

view層回撥介面顯示處理

public class MvpActivity extends BaseActivity implements Vlistener {
    @BindView(R.id.tv_test)
    TextView tvTest;
    @BindView(R.id.tv_msg)
    TextView tvMsg;
    private Plistener plistener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvp);
        ButterKnife.bind(this);
        plistener = new P(this);
    }


    @OnClick(value = R.id.tv_test)
    void onTvTestClick(View view) {
        plistener.doTest("1");
    }


    @OnClick(value = R.id.tv_msg)
    void onTvMsgClick(View view) {
        SubjectPostApi postEntity = new SubjectPostApi();
        postEntity.setAll(true);
        plistener.startPost(MvpActivity.this, postEntity);
    }


    @Override
    public void showProg() {
        showP();
    }

    @Override
    public void dismissProg() {
        dismissP();
    }

    @Override
    public void onNext(String s, String m) {
        tvMsg.setText("返回資料:" + s);
    }

    @Override
    public void onError(ApiException e) {
        tvMsg.setText("錯誤資訊:" + e.getMessage() + "------" + e.getCode());
    }

    @Override
    public void onTestNext(String msg) {
        tvTest.setText("測試返回資料了:" + msg);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

presenter新增介面

事件觸發介面

/**
 * p層提供給v層的介面
 * Created by WZG on 2016/12/26.
 */

public interface Plistener {
    /**
     * http請求
     * @param rxAppCompatActivity
     * @param baseApi
     */
    void startPost(RxAppCompatActivity rxAppCompatActivity, BaseApi baseApi);

    /**
     * 其他方法-演示
     * @param msg
     */
    void doTest(String msg);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

view回撥介面

/**
 * mvp 中p層提供給m層使用的介面
 * Created by WZG on 2016/12/26.
 */

public interface PVlistener {

    /**
     * 測試回撥
     * @param msg
     */
    void testPSuc(String msg);

    /**
     * 成功後回撥方法
     *
     * @param resulte
     * @param mothead
     */
    void onNext(String resulte, String mothead);

    /**
     * 失敗
     * 失敗或者錯誤方法
     * 自定義異常處理
     *
     * @param e
     */
    void onError(ApiException e);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

presenter實現

當觸發以後,完全交給model層處理,當結果返回時,傳遞給view即可

/**
 * presenter兩個介面,一個請求一個回撥
 * 目的:確保Model層不直接操作View層
 * Created by WZG on 2016/12/26.
 */

public class P implements Plistener,PVlistener{

    private Vlistener vlistener;

    private Mlistener mlistener;


    public P(Vlistener viewListener) {
        this.vlistener = viewListener;
        mlistener =new M(this);
    }

    @Override
    public void startPost(RxAppCompatActivity rxAppCompatActivity, BaseApi baseApi) {
        vlistener.showProg();
        mlistener.startPost(rxAppCompatActivity,baseApi);
    }

    @Override
    public void doTest(String msg) {
        mlistener.testDo(msg);
    }


    @Override
    public void testPSuc(String msg) {
        vlistener.onTestNext(msg);
    }


    @Override
    public void onNext(String resulte, String mothead) {
        vlistener.onNext(resulte,mothead);
        vlistener.dismissProg();
    }


    @Override
    public void onError(ApiException e) {
        vlistener.onError(e);
        vlistener.dismissProg();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

model層介面

/**
 * m層提供給p層的介面
 * Created by WZG on 2016/12/26.
 */

public interface Mlistener {

    /**
     * 開始任務
     * @param rxAppCompatActivity
     * @param baseApi
     */
    void startPost(RxAppCompatActivity rxAppCompatActivity, BaseApi baseApi);

    /**
     * 測試介面
     * @param s
     */
    void testDo(String s);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

model層實現

model層中出了實現自定義的介面外,還需要實現Retrofit回撥介面的處理,在伺服器返回資料後及時處理,回撥給presenter層的PVlistener

/**
 * m層資料處理
 * Created by WZG on 2016/12/26.
 */

public class M implements Mlistener, HttpOnNextListener {
    private PVlistener pVlistener;

    public M(PVlistener pVlistener) {
        this.pVlistener = pVlistener;
    }

    @Override
    public void startPost(RxAppCompatActivity rxAppCompatActivity, BaseApi baseApi) {
        HttpManager manager = new HttpManager(this, rxAppCompatActivity);
        manager.doHttpDeal(baseApi);
    }

    @Override
    public void testDo(String s) {
        String msg = "M" + s;
        pVlistener.testPSuc(msg);
    }


    @Override
    public void onNext(String resulte, String mothead) {
        pVlistener.onNext(resulte, mothead);
    }

    @Override
    public void onError(ApiException e) {
        pVlistener.onError(e);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

到這裡一套適用於mvp+RxRetrofit的框架就運用而生了,當然你可以繼續新增功能,這裡只是簡單的給出使用的思路。

實現效果

這裡寫圖片描述


終極封裝專欄

RxJava+Retrofit+OkHttp深入淺出-終極封裝專欄)


原始碼

傳送門-下載封裝原始碼


建議

如果你對這套封裝有任何的問題和建議歡迎加入QQ群告訴我!

相關文章