【Android】完善的mvp架構(gòu)封裝demo(可項目中使用)

相關(guān)知識和簡版架構(gòu)請參考:

【Android】mvp架構(gòu)模式知識匯總 - 簡書

demo地址

github

gitee

本文主要對mvp架構(gòu)中的一些問題處理,從而完善封裝。

1、關(guān)于內(nèi)存泄漏;

說明: 內(nèi)存泄漏主要原因是生命周期長的持有生命周期短的,導致持有的對象想要回收時無法回收。

場景:

其中mvp架構(gòu)中,Presenter必須持有View;

Model一般會有異步請求,需要回調(diào)結(jié)果給Presenter(無論匿名內(nèi)部類方式還是Presenter實現(xiàn)接口方式),那么Model則必定持有Presenter,同時可能需要使用到Context。

在Model中有耗時操作時就會導致此時Presenter和Context無法回收,而View和Context實際上就是Activity。

解決方法:

使用弱引用,封裝在基類中,提供getisDestory方法。每次調(diào)用get前需要先判斷下

示例:BasePresenter中

    /**
     * View是否有被回收
     *
     * @return
     */
    public boolean isViewDestory() {
        if (iViewWeakRef == null) {
            return true;
        }

        V view = iViewWeakRef.get();
        if (view == null) {
            return true;
        }
        if (view instanceof Activity) {
            Activity activity = (Activity) view;
            if (activity.isDestroyed() || activity.isFinishing()) {
                return true;
            }
        }

        return false;
    }
    /**
     * 與view解綁
     */
    public void detachView() {
        if (iViewWeakRef != null) {
            iViewWeakRef.clear();
        }
        iViewWeakRef = null;
        model.destory();
    }

BaseView中

    Context getContext();

BaseCallBack中

    Context getContext();

每次調(diào)用get時需要判斷下

    /**
     * 請求數(shù)據(jù)入口
     * @param url
     */
    @Override
    public void requestData(String url) {
        if (isViewDestory()) {
            return;
        }

        getMvpView().showLoading();
        model.executeGetRequest(url);
    }

2、Context的獲取方式;

使用接口獲取,不要直接傳入保存成成員變量,這樣符合封閉原則,減少持有而需要防止內(nèi)存泄漏的處理。

BaseView中

    Context getContext();

BaseCallBack中

    Context getContext();

如果使用傳入的方式則是

    /**
     * 綁定mvp的View接口
     *
     * @param cxt
     * @param mvpView
     */
    public void attachView(Context cxt, V mvpView) {
        this.mContext = cxt;
        this.iView = mvpView;
    }

這樣同時需要維護mContext、iView兩個變量。

3、Presenter與Model交互方式;

Presenter以實現(xiàn)接口的方式傳給Model,這樣可以Presenter中代碼更簡潔,還可以讓Model弱引用持有Presenter,并且通過接口方式獲取Context,不用再次傳入。

示例:

BaseModel中

public abstract class BaseModel<I extends BaseCallBack> {
    protected WeakReference<I> iCallBackWeakRef;

    public BaseModel(I iCallBack) {
        iCallBackWeakRef = new WeakReference<>(iCallBack);
    }

Presenter中

    @Override
    protected StudentModel createModel(BasePresenter presenter) {
        return new StudentModel(this);
    }
    /**
     * 請求數(shù)據(jù)入口
     * @param url
     */
    @Override
    public void requestData(String url) {
        if (isViewDestory()) {
            return;
        }

        getMvpView().showLoading();
        model.executeGetRequest(url);
    }

如果以匿名內(nèi)部類的方式實現(xiàn)會直接導致內(nèi)存泄漏,同時Presenter中代碼沒那么簡潔。

示例:

Presenter中,此時,Model已經(jīng)隱性強引用了Presenter。

 model.loadData(courseId, new HttpResponse<String>(String.class) {
            @Override
            public void onSuccess(String str) {

            }

            @Override
            public void onError(final String msg) {
               
            }
        });
?著作權(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)容