欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

AndroidT-MVVM深度解耦開發(fā)框架

###前言
自從官方mvp的Sample出來(lái)后,鬧得熱火朝天的mvp,小碼也未能幸免加入MVP大坑中,入坑近2年的MVP的架構(gòu)終于要說(shuō)拜拜了,最近由于公司項(xiàng)目相對(duì)穩(wěn)定,做了一次較大的重構(gòu),原來(lái)的MVP架構(gòu)切換到了T-MVVM。整個(gè)項(xiàng)目清爽了許多。
###問題

創(chuàng)新互聯(lián)公司成立10多年來(lái),這條路我們正越走越好,積累了技術(shù)與客戶資源,形成了良好的口碑。為客戶提供成都網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、國(guó)際域名空間、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。網(wǎng)站是否美觀、功能強(qiáng)大、用戶體驗(yàn)好、性價(jià)比高、打開快等等,這些對(duì)于網(wǎng)站建設(shè)都非常重要,創(chuàng)新互聯(lián)公司通過對(duì)建站技術(shù)性的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究為客戶提供一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。

MVP缺點(diǎn):
 * Presenter中除了邏輯以外,還有大量的View->Model,Model->View的邏輯操作,造成     Presenter臃腫,維護(hù)困難。
 * 對(duì)UI的渲染放在了Presenter中,所以UI和Presenter的交互會(huì)過于頻繁。
 * Presenter過多地渲染了UI,往往會(huì)使得它與特定的UI的交互頻繁。一旦UI變動(dòng),Presenter也需要變
 * 接口暴增,可以說(shuō)代碼量成倍增長(zhǎng),交互都需要通過接口傳遞信息,讓人無(wú)法忍受.

基本上用過mvp的碼友們都能發(fā)現(xiàn)了以上諸多弊端。于是小碼就嘗試從傳統(tǒng)的MVP過度到T-MVVM,深度結(jié)構(gòu),告別繁瑣的接傳遞信息。
如果項(xiàng)目業(yè)務(wù)不是很多或者業(yè)務(wù)相對(duì)簡(jiǎn)單,其實(shí)完全沒有必要使用mvp,反而讓項(xiàng)目變得更為復(fù)雜。

###T-MVVM代碼,如果有幫助記得star哦<https://github.com/SelfZhangTQ/T-MVVM>
基于ViewModel,LiveData,Retrofit,Rxjava實(shí)現(xiàn)T-MVVM體系結(jié)構(gòu)的架構(gòu),泛型限定,深度解耦。

ViewModel優(yōu)點(diǎn):
 * 同步關(guān)聯(lián)生命周期,
 * 數(shù)據(jù)共享 ,
 * 復(fù)用性強(qiáng) ,
LiveData優(yōu)點(diǎn):
 * 確保UI界面的數(shù)據(jù)狀態(tài),
 * 沒有內(nèi)存泄漏,不會(huì)因?yàn)锳ctivity的不可見導(dǎo)致Crash,
 * 不用再人為的處理生命周期,
 * 共享資源,

此架構(gòu)未使用DataBinding原由:

* 數(shù)據(jù)綁定增加Bug調(diào)試難度,
* 復(fù)雜的頁(yè)面,model也會(huì)很大,雖然使用方便了也很容易保證了數(shù)據(jù)的一致性,當(dāng)時(shí)長(zhǎng)期持有,不利于釋放內(nèi)存,
* 數(shù)據(jù)雙向綁定不利于View重用,

###T-MVVM架構(gòu)分層代碼
1:先定義BaseViewModel基類

 /**
  * @author:tqzhang on 18/7/26 16:15
  */
  public class BaseViewModel<T extends BaseRepository> extends AndroidViewModel {

    public T mRepository;

    public BaseViewModel(@NonNull Application application) {
        super(application);
        mRepository = TUtil.getNewInstance(this, 0);
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        if (mRepository != null) {
           mRepository.unSubscribe();
        }

   }
 }

BaseViewModel通過泛型類型參數(shù)BaseRepository子類初始化Repository數(shù)據(jù)倉(cāng)庫(kù),同時(shí)在activity/fragment走onDestroy()生命周期方法時(shí) BaseViewModel回調(diào)onCleared,即頁(yè)面銷毀是用來(lái)取消網(wǎng)絡(luò)請(qǐng)求或資源釋放等操作。

正常開發(fā)一般不建議直接通過ViewModel獲取網(wǎng)絡(luò)數(shù)據(jù),這里我們將工作交給一個(gè)新的模塊Repository。Repository只負(fù)責(zé)數(shù)據(jù)處理,提供干凈的api,方便切換數(shù)據(jù)來(lái)源。

2:再定義BaseRepository

public abstract class BaseRepository {

     protected ApiService apiService;

     public BaseRepository() {
             if (null == apiService) {
                 apiService = HttpHelper.getInstance().create(ApiService.class);
             }
     }

     private CompositeSubscription mCompositeSubscription;

     protected void addSubscribe(Subscription subscription) {
            if (mCompositeSubscription == null) {
                mCompositeSubscription = new CompositeSubscription();
            }
           mCompositeSubscription.add(subscription);
      }

     public void unSubscribe() {
             if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
            mCompositeSubscription.clear();
    }
}

BaseRepository中內(nèi)容相對(duì)簡(jiǎn)單,主要是獲取ApiService和網(wǎng)絡(luò)請(qǐng)求訂閱容器,方便管理網(wǎng)絡(luò)請(qǐng)求。

3:然后自定義AbsLifecycleFragment基類繼承BaseFragment,BaseFragment可自行編寫。如不需要使用T-MVVM,可自行繼承BaseFragment,互不影響。

 public abstract class AbsLifecycleFragment<T extends BaseViewModel> extends BaseFragment  {

       protected T mViewModel;
       /**
        * init view
        * @param state
        */
       @Override
       public void initView(Bundle state) {
            mViewModel = VMProviders(this, TUtil.getInstance(this, 0));
          if (null != mViewModel) {
            dataObserver();
          }
       }

      /**
       * create ViewModelProviders
       *
       * @return ViewModel
       */
      protected <T extends ViewModel> T VMProviders(BaseFragment fragment, @NonNull Class<T> modelClass) {
           return ViewModelProviders.of(fragment).get(modelClass);
      }

      protected void dataObserver() {

      }

     /**
      * 獲取網(wǎng)絡(luò)數(shù)據(jù)
      */
      protected void getRemoteData() {

      } 

    }

在initView方法中通過BaseViewModel子類泛型類型參數(shù)獲取Class<T>,在通過ViewModelProviders.of(fragment).get(modelClass))實(shí)例化ViewModel,
到此我們的基類基本編寫完畢。

4:下面我們以一個(gè)簡(jiǎn)單業(yè)務(wù)實(shí)戰(zhàn)下,獲取文章列表。

4-1:ArticleFragment

/**
* @author:zhangtianqiu on 18/7/2 14:40
*/
public class ArticleFragment extends AbsLifecycleFragment<ArticleViewModel> {  
 protected TRecyclerView mRecyclerView;
 protected StaggeredGridLayoutManager layoutManager;
 protected MultiTypeAdapter adapter;

 public static ArticleFragment newInstance() {
    return new ArticleFragment();
 }

 @Override
 public int getLayoutResId() {
    return R.layout.fragment_list;
 }

 @Override
 public void initView(Bundle state) {
    super.initView(state);
    layoutManager=new new StaggeredGridLayoutManager(1,  StaggeredGridLayoutManager.VERTICAL);
    //獲取網(wǎng)絡(luò)數(shù)據(jù)
    getRemoteData();
 }

 //初始化adapter
 public void initAdapter(){
   adapter= new MultiTypeAdapter.Builder<>()
           .bindArray(ArticleInfoVo.class, new ArticleRem1ItemHolder(context)
            , new ArticleRem2ItemHolder(context)
            , new ArticleRem3ItemHolder(context))
           .bind(HeaderVo.class, new HeaderViewHolder(context, rogressStyle.Pacman))
           .bind(FootVo.class, new FootViewHolder(context, ProgressStyle.Pacman))
           .build();

 //數(shù)據(jù)觀察
 @Override
 protected void dataObserver() {
    mViewModel.getArticleList().observe(this, articleVo -> {
        if (null != articleVo) {
           mRecyclerView.refreshComplete(articleVo.data.list, false);
        }
    });
 }
 //獲取網(wǎng)絡(luò)數(shù)據(jù)
 @Override
 protected void getRemoteData() {
     mViewModel.getArticleList(typeId, lastId);
 }
}

我們可以看出來(lái)ArticleFragment中只有UI初始化,發(fā)請(qǐng)網(wǎng)絡(luò)請(qǐng)求action以及數(shù)據(jù)觀察更新UI,列表展示用了TRecyclerView,歡迎star哦面向holder開發(fā)高復(fù)用,多類型的刷新庫(kù),從此只關(guān)心你的列表的Item展示。
通過泛型除去了MVP中通過接口傳遞信息的大量代碼,
從此see you Mass implementation of interfaces。

4-1:ArticleViewModel

/**
* @author:tqzhang on 18/7/26 16:15
*/
public class ArticleViewModel extends BaseViewModel<ArticleRepository> {

     private MutableLiveData<ArticleVo> mArticleData;

     public ArticleViewModel(@NonNull Application application) {
          super(application);
     }

     public LiveData<ArticleVo> getArticleList() {
          if (mArticleData == null) {
              mArticleData = new MutableLiveData<>();
          }
         return mArticleData;
     }

    public void getArticleList(String lectureLevel1, String lastId) {
          mRepository.loadArticleRemList(new CallBack<ArticleVo>() {
        @Override
        public void onNext(ArticleVo articleObject) {
            mArticleData.postValue(articleObject);
        }

        @Override
        public void onError(String e) {

        }            }
    });
}

ArticleViewModel中持有數(shù)據(jù)觀察容器LiveData和真正發(fā)起網(wǎng)絡(luò)請(qǐng)求動(dòng)作,在接收到服務(wù)端返回的數(shù)據(jù)通過
mArticleData.postValue(articleObject);通知Observer數(shù)據(jù)的更改,此處需注意的是,setValue方法只能在主線程中調(diào)用,postValue可以在任何線程中調(diào)用,如果是在后臺(tái)子線程中更新LiveData的值,必須調(diào)用postValue。

4-3:ArticleRepository

/**
 * @author:tqzhang on 18/7/28 13:00
 */
 public class ArticleRepository extends BaseRepository {

      public void loadArticleRemList(final CallBack<ArticleVo> listener) {
          addSubscribe(apiService.getArticleRemList()
                .compose(RxSchedulers.io_main())
                .subscribe(new RxSubscriber<ArticleVo>() {

                    @Override
                    public void onSuccess(ArticleVo articleObject) {
                        listener.onNext(articleObject);
                    }

                    @Override
                    public void onFailure(String msg) {
                        listener.onError(msg);
                    }
            }));

}

最后我們的ArticleRepository中就提供數(shù)據(jù),此處只提供了網(wǎng)絡(luò)層的數(shù)據(jù),在實(shí)際應(yīng)用中可拆分類loacl data和remote data,可根據(jù)項(xiàng)目需求自行處理。
至此咋們一個(gè)簡(jiǎn)單業(yè)務(wù)代碼就完成了,是驢子是馬,拉出來(lái)溜溜就知道,實(shí)踐出真知,效果圖奉上:
Android T-MVVM深度解耦開發(fā)框架

項(xiàng)目地址github地址:<https://github.com/SelfZhangTQ/T-MVVM>,歡迎大家交流,star。

當(dāng)前題目:AndroidT-MVVM深度解耦開發(fā)框架
當(dāng)前網(wǎng)址:http://aaarwkj.com/article24/gihije.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、軟件開發(fā)、網(wǎng)站設(shè)計(jì)、關(guān)鍵詞優(yōu)化、網(wǎng)站改版用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
麻豆影片在线免费观看| 日韩av手机在线不卡| 国产精品白嫩初高中害羞小美女| 每日更新中文字幕粉嫩av| 亚洲国产精品97视频| 日韩中文字幕欧美国产| 视频精品一区二区在线观看| 免费亚洲一区二区三区| 欧美日韩电影一区二区三区| 国产欧美一区二区另类精品| 精品国产一区二区av麻豆| 国产麻豆三级在线观看| 欧美午夜精品一二三区| 国产精品毛片一区二区三区| 日本韩国欧美在线一区| 女同亚洲一区二区三区| 日韩精品中文字幕国产精品| 麻豆久久精品国产亚洲精品超碰热| 亚洲欧美日韩乱码综合久久| 蜜桃视频在线观看视频免费| 高级会所口爆视频在线播放视频| 国产粉嫩一区二区三区在线观看| 日韩欧美一区二区免费| 日韩亚洲人成网站在线播放| 成人国产精品2021| 日韩免费高清不卡视频| 久久精品国产亚洲av高清不卡| 成人性生活三级黄色片| 91在线人妻一区二区三区| 国产午夜三级视频在线观看| 亚洲华人在线免费视频| 日本束缚人妻一区二区三区| 亚洲国产精品自拍视频| 亚洲一区二区三区四区国产| 一区二区日韩视频九一蜜桃| 日韩精品91一区二区| 野花日本免费高清完整| 亚洲最大成人av在线| 亚洲综合色婷婷七月丁香| 天天操天天干夜夜射| 亚洲乱码一区二区在线|