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

相關(guān)知識(shí)請(qǐng)參考:

【Android】mvvm架構(gòu)模式知識(shí)匯總 - 簡(jiǎn)書(shū)

demo地址

GitHub - askskysun/ImproveMvvmDemo

ImproveMvvmDemo: 封裝好的MvvmDemo,可以直接在項(xiàng)目中使用

分工

View

Activity處理UI交互相關(guān);

使用注意:

1、需要判斷的UI處理邏輯放在Activity,不要把顯示邏輯放在xml;

2、詳細(xì)DataBinding規(guī)范參考:

DataBinding實(shí)用指南 - 簡(jiǎn)書(shū)

點(diǎn)擊事件處理

在activity中設(shè)置一個(gè)接口,點(diǎn)擊事件統(tǒng)一在接口處理,通過(guò)view的id辨別點(diǎn)擊按鈕,因?yàn)辄c(diǎn)擊是用戶(hù)的操作,屬于UI層面的,統(tǒng)一在activity。

/**
 * <pre>
 * 點(diǎn)擊事件,使用自定義接口,在activity中統(tǒng)一調(diào)用
 * </pre>
 */
public interface OnClickPresenter extends View.OnClickListener{
    @Override
    void onClick(View v);
}

Activity中

 //點(diǎn)擊事件的處理
        binding.setPresenter(this);
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.click1_tv:
                fanYiViewModel.getTranslateData();
                break;
            case R.id.click2_tv:
                Toast.makeText(MVVMActivity.this, "點(diǎn)擊了2", Toast.LENGTH_SHORT).show();
                break;
        }
    }

ViewModel

用于保存數(shù)據(jù),和數(shù)據(jù)交互邏輯;

顯示數(shù)據(jù)通過(guò)LiveData傳給Activity;數(shù)據(jù)處理邏輯、耗時(shí)操作交給Model;

使用注意:

1、記住絕對(duì)不可以直接去創(chuàng)建ViewModel實(shí)例,一定要通過(guò)ViewModelProvider(ViewModelStoreOwner)構(gòu)造函數(shù)來(lái)獲取。因?yàn)槊看涡D(zhuǎn)屏幕都會(huì)重新調(diào)用onCreate()方法,如果每次都創(chuàng)建新的實(shí)例的話(huà)就無(wú)法保存數(shù)據(jù)了;

2、由于Model會(huì)有耗時(shí)操作,但ViewModel隨時(shí)需要回收,為了防止內(nèi)存泄漏,調(diào)用Model方法時(shí)不要使用匿名內(nèi)部類(lèi)做回調(diào)或者直接把ViewModel傳給Model。使用一個(gè)自定義的接口傳給Model,Model用弱引用持有,這個(gè)可在基類(lèi)處理;

3、初始化可變數(shù)據(jù)放在ViewModel構(gòu)造器中;不可改變的數(shù)據(jù)在Activity處理,或者xml中寫(xiě)默認(rèn)值;

Model

數(shù)據(jù)處理,網(wǎng)絡(luò)請(qǐng)求、資源請(qǐng)求等耗時(shí)操作、異步操作;

需要處理的問(wèn)題

ViewModel與Model內(nèi)存泄漏問(wèn)題

由于Model會(huì)有耗時(shí)操作,生命周期可能比ViewModel長(zhǎng),所以在兩者交互時(shí)存在內(nèi)存泄漏的問(wèn)題;

在此我們可以用定義回調(diào)接口,從ViewModel傳給Model,在Model中弱引用持有,Model進(jìn)行回調(diào)時(shí)注意判空。這些我們使用泛型寫(xiě)在基類(lèi)里面。

1、Model中持有接口;

public abstract class BaseModel<I> {

    /**
     * 回調(diào)給ViewModel的接口
     */
    protected WeakReference<I> iCallBackWeakRef;

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

2、ViewModel必然持有Model,我們寫(xiě)在基類(lèi);

public abstract class BaseViewModel<M extends BaseModel> extends ViewModel {

    protected M model;

    public BaseViewModel() {
        model = createModel();
    }

    protected abstract M createMory();
    }

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

3、ViewModel把接口傳給Model;

public class TranslateViewModel extends BaseViewModel<TranslateModel> implements OnTranslateCallBack {

    @Override
    protected TranslateModel createModel() {
        return new TranslateModel(this);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容