google 官方mvp實例的實踐之mvp-databinding-Rxjava(一)

原文地址

前言

我根據(jù)在項目中使用過 mvp馍驯、mvp+databinding、mvp+Rxjava ,通過閱讀google給出的mvp各種示例朵纷,對mvp進(jìn)行總結(jié)實現(xiàn)mvp+databinding+Rxjava的實現(xiàn)方式;

我對于mvp-databinding-Rxjava的理解

我認(rèn)為在android中M 就是Model 是操作數(shù)據(jù)的地方永脓,在M 中可以調(diào)用各種處理數(shù)據(jù)的Manager袍辞,View 是activity,fragment等常摧,在加上databinding可以在綁定數(shù)據(jù)搅吁,p是連接m與v之間的橋梁,以及控制一些需要在主線程實現(xiàn)的數(shù)據(jù)通過RxAndroid 切換到主線程中落午;我認(rèn)為使用databinding的好處可以不用寫findview谎懦,顯示數(shù)據(jù)的時候直接set進(jìn)去就可以了,不需要通過id在settext的方式板甘,還有就是有一些數(shù)據(jù)是可以不需要切換ui線程党瓮,直接set就可以;而使用Rxjava的好處是可以不需要通過handler就可以實現(xiàn)對線程的切換盐类,可以直接顯示數(shù)據(jù)寞奸;

學(xué)習(xí)經(jīng)歷

在項目中使用過的mvp模式,也使用過mvvm模式在跳,但是一直不知道怎么實現(xiàn)是對的枪萄,在使用過程中總是感覺有一些,感覺不舒服的地方猫妙,先說說我是用mvp的經(jīng)歷瓷翻,主要是用過三種方式,最開始是使用zjutkz的一篇博客選擇恐懼癥的福音!教你認(rèn)清MVC,MVP和MVVM,在這篇博客中我學(xué)會了如何使用mvp齐帚,發(fā)現(xiàn)這個模式實在的太美了妒牙,業(yè)務(wù)與頁面完全分離,實現(xiàn)業(yè)務(wù)的時候只需要實現(xiàn)業(yè)務(wù)就可以对妄,實現(xiàn)頁面只需要實現(xiàn)自己的頁面就好了湘今,不需要關(guān)注太多,而且如果哪一天剪菱,經(jīng)理說界面哪里不好看摩瞎,需要改,直接修改頁面就好了孝常,完全不需要關(guān)注業(yè)務(wù)旗们,如果要是說需求有變化,那么直接改變業(yè)務(wù)模塊就可以了构灸,而且各個模塊之間盡量的實現(xiàn)了解耦上渴,方便以后修改,但是在使用過程中感覺有點麻煩喜颁,之后又看了 MvpFrame一個比較簡單的mvp架構(gòu)驰贷,但是我發(fā)現(xiàn)在使用過程中對項目的侵入性很強(qiáng),也有可能是我的強(qiáng)迫癥洛巢,總是感覺沒有真正的了解mvp括袒,于是決定閱讀google給出的mvp示例 google ,通過在項目中的使用,得出自己的mvp實現(xiàn)方式稿茉;

開始放碼

demo地址
BasePresenter 中主要為了與Activity或者fragment中的生命周期統(tǒng)一锹锰,避免內(nèi)存泄漏

public interface BasePresenter {    
  void onResume(Context context);  
  void onStop();    
  void onDestroy();
}

BaseView中只是對P進(jìn)行綁定,如果要是在Activity中使用可以不去管這個方法漓库;

public interface BaseView<T> {    void setPresenter(T presenter);}

BaseModel 對基礎(chǔ)數(shù)據(jù)處理的實現(xiàn),對于事件傳遞我使用了rxjava實現(xiàn)的Rxbus恃慧,不了解的可以看一下我之前的一篇rxbus的博客RxJava實現(xiàn)事件總線 Rxbus代替eventbus 減少庫的使用

/**
 * @desc:
 * @author: Jiangcy
 * @datetime: 2016/9/3
 */
public abstract class BaseModel<T> {
    private Subscription rxMainBus;
    private Subscription rxThreadBus;
    protected Context mContext;
    //設(shè)置默認(rèn)接受類型為全部接收
    private
    @EventType.ReceiveType
    int recieveType = EventType.REC_ALL;
    protected T mPresenter;

    public BaseModel(T mPresenter) {
        this.mPresenter = mPresenter;
    }

    /**
     * 進(jìn)入
     */
    public void onResume(Context mContext) {
        this.mContext = mContext;
        initRxbus();
    }

    /**
     * 初始化接收類型
     *
     * @param recieveType
     */
    public void initReciever(@EventType.ReceiveType int recieveType) {
        this.recieveType = recieveType;
    }

    ;

    /**
     * 注冊rxbus事件接收
     */
    private void initRxbus() {
        rxMainBus = RxBus.getDefault().toObserverable(RxEvent.class)
                .filter(new Func1<RxEvent, Boolean>() {
                    @Override
                    public Boolean call(RxEvent rxEvent) {
                        //此處可以通過Rxjava的filter過濾函數(shù)對數(shù)據(jù)進(jìn)行過濾,從而得到自己想要的數(shù)據(jù)
                        if ((rxEvent.reciveType == recieveType ||
                                rxEvent.reciveType == EventType.REC_ALL) && (rxEvent.threadType ==
                                EventType.THREAD_ALL || rxEvent.threadType == EventType.THREAD_UI)) {
                            return true;
                        }
                        return false;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//設(shè)置為主線程接收數(shù)據(jù)
                .subscribe(new Action1<RxEvent>() {
                               @Override
                               public void call(RxEvent rxEvent) {
                                   onMainEvent(rxEvent.eventAction, rxEvent.event);
                               }
                           },
                        new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                // TODO: 處理異常
                            }
                        });

        /**
         *
         */
        rxThreadBus = RxBus.getDefault().toObserverable(RxEvent.class)
                .filter(new Func1<RxEvent, Boolean>() {
                    @Override
                    public Boolean call(RxEvent rxEvent) {
                        //此處可以通過Rxjava的filter過濾函數(shù)對數(shù)據(jù)進(jìn)行過濾渺蒿,從而得到自己想要的數(shù)據(jù)
                        if ((rxEvent.reciveType == recieveType ||
                                rxEvent.reciveType == EventType.REC_ALL) && (rxEvent.threadType ==
                                EventType.THREAD_ALL || rxEvent.threadType == EventType.THREAD_CHILD)) {
                            return true;
                        }
                        return false;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//設(shè)置為子線程接收數(shù)據(jù)
                .subscribe(new Action1<RxEvent>() {
                               @Override
                               public void call(RxEvent rxEvent) {
                                   onThreadEvent(rxEvent.eventAction, rxEvent.event);
                               }
                           },
                        new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                // TODO: 處理異常
                            }
                        });
    }


    public abstract void onMainEvent(String action, Object event);

    public abstract void onThreadEvent(String action, Object event);


    /**
     * 解除事件的注銷痢士,以保證不出現(xiàn)內(nèi)存泄漏
     */
    public void onDestroy() {
        if (rxMainBus != null && !rxMainBus.isUnsubscribed()) {
            rxMainBus.unsubscribe();
        }
        if (rxThreadBus != null && !rxThreadBus.isUnsubscribed()) {
            rxThreadBus.unsubscribe();
        }
        mContext = null;
    }
}

還有兩個我封裝的基礎(chǔ)類需要了解一下,不想看的這一步可以掠過嘿嘿茂装,這兩個基礎(chǔ)類主要是通過封裝減少代碼怠蹂;這個目前只是簡單的封裝以后還會對這些部分進(jìn)一步的進(jìn)行封裝;
BaseActivity

public abstract class BaseActivity extends AppCompatActivity {
    private ViewDataBinding binding;

    protected abstract  int getLayoutId();

    protected abstract void initBinding(ViewDataBinding binding);

    protected abstract void initPresenter();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this,getLayoutId());
        initBinding(binding);

    }

    @CallSuper
    @Override
    protected void onResume() {
        initPresenter();
        super.onResume();
    }

    @CallSuper
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}

BaseDialog

public abstract class BaseDialog extends Dialog implements Dialog.OnDismissListener{

    private Context mContext;
    private ViewDataBinding binding;

    public BaseDialog(Context context) {
        super(context);
        mContext = context;
    }

    public BaseDialog(Context context, int themeResId) {
        super(context, themeResId);
        mContext = context;
    }

    protected BaseDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
        mContext = context;
    }

    protected abstract int getLayoutId();

    protected abstract void initBinding(ViewDataBinding binding);

    protected abstract void initInfo(Object... objects);


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.inflate(LayoutInflater.from(mContext),getLayoutId(),null,false);
        setContentView(binding.getRoot());
    }

    @Override
    protected void onStart() {
        super.onStart();
        setOnDismissListener(this);
    }

    public void showDialog(){
        if(isShowing())return;
        show();
    }

    public void closeDialog(){
        if(!isShowing())return;
        dismiss();
    }
}

為防止代碼量過大少态,我將會把具體實現(xiàn)方式放在下一篇文章里面給出城侧,google 官方mvp實例的實踐之mvp-databinding-Rxjava(二)

demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市彼妻,隨后出現(xiàn)的幾起案子嫌佑,更是在濱河造成了極大的恐慌豆茫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屋摇,死亡現(xiàn)場離奇詭異揩魂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)炮温,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門肤京,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茅特,你說我怎么就攤上這事∑逭恚” “怎么了白修?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長重斑。 經(jīng)常有香客問我兵睛,道長,這世上最難降的妖魔是什么窥浪? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任祖很,我火速辦了婚禮,結(jié)果婚禮上漾脂,老公的妹妹穿的比我還像新娘假颇。我一直安慰自己,他們只是感情好骨稿,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布笨鸡。 她就那樣靜靜地躺著,像睡著了一般坦冠。 火紅的嫁衣襯著肌膚如雪形耗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天辙浑,我揣著相機(jī)與錄音激涤,去河邊找鬼。 笑死判呕,一個胖子當(dāng)著我的面吹牛倦踢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侠草,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼硼一,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了梦抢?” 一聲冷哼從身側(cè)響起般贼,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后哼蛆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蕊梧,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年腮介,在試婚紗的時候發(fā)現(xiàn)自己被綠了肥矢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡叠洗,死狀恐怖甘改,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灭抑,我是刑警寧澤十艾,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站腾节,受9級特大地震影響忘嫉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜案腺,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一庆冕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧劈榨,春花似錦访递、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至邑闺,卻和暖如春跌前,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陡舅。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工抵乓, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人靶衍。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓灾炭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颅眶。 傳聞我的和親對象是個殘疾皇子蜈出,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,144評論 25 707
  • 當(dāng)我們遇到危險的時候铡原,你的腦子里第一浮現(xiàn)的是什么偷厦?一個五歲的女孩,在遇到男性的侵犯的時候燕刻,她該怎么做只泼?如果你有過同...
    大婧婧姐閱讀 476評論 2 0
  • 文|八兩的奇妙世界呀 01 哈哈哈,今天正式邁入25歲了耶卵洗!cheers请唱! 別人都說25歲是一個坎兒,皮膚開始走向...
    八兩的奇妙世界呀閱讀 313評論 2 3
  • Redis 的 list 類型其實就是一個每個子元素都是 string 類型的雙向鏈表过蹂。主要功能是 push十绑、po...
    鬭闢閱讀 320評論 0 0
  • 看了一篇叫《陌生人我為什么要幫你》的文章,突然覺得有些話堵在心里不吐不快: 那就是我們?yōu)槭裁匆芙^一個人的求助酷勺,難...
    慕如雪閱讀 1,201評論 3 0