欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android MVP模式面向接口寫法

 更新時間:2023年05月12日 09:16:27   作者:小明杰  
這篇文章主要介紹了Android MVP模式面向接口寫法,MVP模式也出來好幾年了,很成熟所以也導致寫法有很多種,google提供了多種mvp模式,但我今天只講解最簡單的面向接口,需要詳細了解可以參考下文

首先我們需要知道m(xù)vp所代表的含義,m即model可以理解成用來獲取數(shù)據(jù)和處理數(shù)據(jù),v即view可以看成activity和fragment用來顯示數(shù)據(jù)和處理交互,p即presenter可以理解成用來提供數(shù)據(jù)。

三者關(guān)系:m層用來獲取數(shù)據(jù)然后將數(shù)據(jù)提供給p層,p層拿到數(shù)據(jù)后通過v層展示,其中m層和v層是不能直接進行交互的,通過p層這個橋梁進行交互。這其中p層會持有v層和m層的引用。(先讀懂)

理解上面的說法下面我們直接上手代碼:

為了減少接口文件我們可以把接口都聲明在Contract內(nèi)

public interface ContentContract {
    interface Model {
    }
    interface View {
    }
    interface Presenter {
    }
}
//這樣我們不需要寫三個接口文件

然后分別實現(xiàn)三個接口與之對應(yīng)的m層,v層,p層

//model
public class ContentModel implements ContentContract.Model {
}
//view
public class MainActivty extends BaseQuickActivty implements ContentContract.View {
}
//presenter
public class ContentPresenter implements ContentContract.Presenter {
}

首先我們需要考慮的是在v層我們需要做一些什么處理,然后在定義我們的方法。假如我們需要獲取首頁的banner數(shù)據(jù),這時候就可以在view中聲明一個方法用來接收banner數(shù)據(jù)。

public interface ContentContract {
    interface Model {
    }
    interface View {
    void getBanner(String str);
    }
    interface Presenter {
    }
}
//這時候activity實現(xiàn)此方法
public class MainActivty extends BaseQuickActivty implements ContentContract.View {
    @Override
    public void getBanner(String  str) {
    }
}

當v層已經(jīng)有了接收數(shù)據(jù)的方法時,那么數(shù)據(jù)從何而來了?我們在之前說過m層是用來獲取數(shù)據(jù)的 所以我們可以在m層中定義一個請求網(wǎng)絡(luò)的方法。

//
public class ContentModel implements ContentContract.Model {
      //獲取banner
     public void sendHttpBannerData(OnListener<String> on){
          //這里需要考慮一個問題,就是每次獲取請求后的數(shù)據(jù),我們需要傳遞給p層,所以需要一個回調(diào)處理
          //我們可以對m層進一步封裝下
          //代碼示例  
          okgo.post().ex(new CallBack(){
             public void onSucces(String str){
                    on.onSuccess(str);
              }
              public void onFail(){
                     on.onFail();
              }
             });
   }
}
//封裝后的modle層  ,先提取一個基類BaseModel
public interface BaseModel<T> {
    interface OnListener<T> {
        void onSuccess(T t);
        void onFail(int code, String msg);
    }
}
//modle實現(xiàn)
 interface Model<T> extends BaseModle<T> {
    }

現(xiàn)在數(shù)據(jù)獲取的方式已經(jīng)有了,那怎么傳遞給p層呢?我們在之前也說過p層會持有m層的引用,所以我們可以在p層中調(diào)用層方法。

public class ContentPresenter implements ContentContract.Presenter {
    private ContentModel mModel;
    private ContentContract.View mView;
    //當初始化的時候  同時持有v層和m層引用
    public ContentPresenter(ContentContract.View m) {
        mView=m;
        mModel = new ContentModel();
    }
    //定義一個send方法,在該方法中調(diào)用m層的請求數(shù)據(jù)方法
     public void send(){
           mModel.sendHttpBannerData(new BaseModel.OnListener<String>() {
               @Override
               public void onSuccess(String s) {
                    //這里就可以直接使用v層方法處理數(shù)據(jù),在v層中我們已經(jīng)實想該函數(shù)
                    mView.getBanner(s);
               }
               @Override
               public void onFail(int code, String msg) {
               }
           });
    }
}

最后一步就是初始化p

public class MainActivty extends BaseQuickActivty implements ContentContract.View {
@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化p
        ContentPresenter contentPresenter = new ContentPresenter(this);
        contentPresenter.send();//調(diào)用p層的send方法 開始請求數(shù)據(jù)
    }
    @Override
    public void getBanner(String  str) {
    }
}

這樣我們就可以交互了,在接口中我們可以根據(jù)自己的需求增加方法,可以提供基類,這樣沒必要每次都重寫方法,可以將一些通用的放在基類中。(可以先消化下,接下來我們做進一步的處理和避免內(nèi)存泄漏問題)

我們分析下不足之處。

每一個presenter都需要每次重寫相同代碼,手動釋放p等不足之處。所以我們先從presenter入手.

/**
 * 基類 presenter  綁定view
 *
 * @param <T>
 */
public abstract class BasePresenter<T> {
    //弱引用 
    private WeakReference<T> mWeakReference;
    private ReferenceQueue<T> mReferenceQueue = new ReferenceQueue<>();
    /**
     * 添加view進入隊列
     *
     * @param t
     */
    public void attachView(T t) {
        mWeakReference = new WeakReference<T>(t);
    }
    public T getView() {
        return mWeakReference.get();
    }
    /**
     * 判斷是否綁定過view
     *
     * @return true 綁定
     */
    public boolean isViewAttachecd() {
        return mWeakReference != null && mWeakReference.get() != null;
    }
    /**
     * 清除view,這樣不用每次手動釋放
     */
    public void deleteAttach() {
        if (mWeakReference != null) {
            mWeakReference.clear();
            mWeakReference = null;
        }
    }
}

接著我們改進activity或者fragment的基類base

**
 * activity 基類
 * v 代表 view
 * t presenter
 */
public abstract class BaseQuickActivity<V, T extends BasePresenter<V>> extends AppCompatActivity {
    protected T mPresenter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();
        //這里做一下非空判斷 有可能某些模塊不需要mvp模式
        if (mPresenter != null) {
            mPresenter.attachView((V) this);
        }
    }
    protected abstract T createPresenter();
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null) {
            mPresenter.deleteAttach();
        }
    }
}
//fragment 一樣的寫法

這樣我們基本上完善了mvp模式。mvp給我?guī)淼暮锰幒芏?,高度解耦,代碼結(jié)構(gòu)清晰(以前ac或者ft可以達到上千行代碼,現(xiàn)在都交給了p和m),便于測試(不會)。但是同時也有缺點,第一感知就是類增多了。第二感知就是在交互時有些時候不方便。
上述結(jié)構(gòu)體還是可以更加完善的,可以用eventbus或者rxjava用于溝通的橋梁和數(shù)據(jù)分發(fā)。

到此這篇關(guān)于Android MVP模式的寫法淺析的文章就介紹到這了,更多相關(guān)Android MVP模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論