MVP与Jetpack组合应用

搭建MVC框架

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private ArrayList<String> list = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        listView = findViewById(R.id.listView);
        listView.setAdapter(new GoodsAdapter(this,list));

    }

    private void initData() {
        list.add("apple");
        list.add("banana");
        list.add("orange");
        list.add("pear");
        list.add("strawberry");
        list.add("watermelon");
    }

}

public class GoodsAdapter extends BaseAdapter {

    private Context context = null;
    private List<String> dataList;

    public GoodsAdapter(Context context, List<String> dataList) {
        this.context = context;
        this.dataList = dataList;
    }

    @Override
    public int getCount() {
        return dataList.size();
    }

    @Override
    public Object getItem(int position) {
        return dataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView textView;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_listview, null);
            textView = convertView.findViewById(R.id.textView);
            convertView.setTag(textView);
        } else {
            textView = (TextView) convertView.getTag();
        }
        textView.setText(dataList.get(position));
        return convertView;
    }
}

MVC框架有一个致命的问题是Activity的内存泄漏,使用MVP是有办法根除内存泄漏的。

搭建MVP基本框架

MVP的核心思想:MVC中原来的UI逻辑抽象成View接口,原来的业务逻辑抽象成Presenter接口,Model还是原来的Model。

public interface IBaseView {
    void showErrorMessage(String msg);
}

public interface IGoodsModel {
    void loadGoodData(OnLoadListener onLoadListener);

    interface OnLoadListener {
        void onComplete(List<String> goods);

        void onError(String msg);
    }
}
public class GoodsModel implements IGoodsModel {
    @Override
    public void loadGoodData(OnLoadListener onLoadListener) {
        onLoadListener.onComplete(getData());
    }

    public List<String> getData() {
        ArrayList<String> list = new ArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("orange");
        list.add("pear");
        list.add("strawberry");
        list.add("watermelon");
        return list;
    }
}
public class GoodsPresenter<T extends IGoodsView> {

    //持有View层的引用
    IGoodsView iGoodsView;

    //持有Model层的引用
    IGoodsModel iGoodsModel = new GoodsModel();

    public GoodsPresenter(T view){
        iGoodsView = view;
    }
    public void fetch(){
        if(iGoodsView!=null && iGoodsModel!=null){
            iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
                @Override
                public void onComplete(List<String> goods) {
                    iGoodsView.showGoodsView(goods);
                }

                @Override
                public void onError(String msg) {

                }
            });
        }
    }
}
public class MainActivity extends AppCompatActivity implements IGoodsView {

    private ListView listView;
    GoodsPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);
        presenter = new GoodsPresenter(this);
        presenter.fetch();
    }


    @Override
    public void showGoodsView(List<String> data) {
        listView.setAdapter(new GoodsAdapter(this, data));
    }

    @Override
    public void showErrorMessage(String msg) {

    }
}

最基本的MVP框架搭建完成,这样写很容易发生内存泄漏。为什么呢?

现在Presenter持有View的引用,如果GoodsPresenter在做网络操作的时候时间比较长,用户随时都会退到前台,但是GoodsPresenter一直持有Activity的引用,就会造成内存泄漏,和MVC的问题是一样的。

该怎么处理呢?可以使用弱引用

性能优化,根除Activity内存泄漏

public class GoodsPresenter<T extends IGoodsView> {

    //持有View层的引用
    public WeakReference<T> iGoodsView;

    //持有Model层的引用
    IGoodsModel iGoodsModel = new GoodsModel();

    public GoodsPresenter(T view) {
        iGoodsView = new WeakReference<>(view);
    }

    public void fetch() {
        if (iGoodsView != null && iGoodsModel != null) {
            iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
                @Override
                public void onComplete(List<String> goods) {
                    iGoodsView.get().showGoodsView(goods);
                }

                @Override
                public void onError(String msg) {

                }
            });
        }
    }
}

虽然弱引用能解决内存泄漏问题,但是延迟性比较高。

弱引用是在下一次GC的时候回收弱引用,为了使回收的动作更快一点,可以采用绑定/解绑的方式。

扫描二维码关注公众号,回复: 11897501 查看本文章

attachView():在Activity/Fragment执行生命周期方法onCreate()的时候

detachView():Activity/Fragment执行执行生命周期方法onDestroy()的时候

public class GoodsPresenter<T extends IGoodsView> {

    //持有View层的引用
    public WeakReference<T> iGoodsView;

    //持有Model层的引用
    IGoodsModel iGoodsModel = new GoodsModel();

    public void attachView(T view) {
        iGoodsView = new WeakReference<>(view);
    }

    public void detachView() {
        if (iGoodsView != null) {
            iGoodsView.clear();
            iGoodsView = null;
        }

    }

    public void fetch() {
        if (iGoodsView != null && iGoodsModel != null) {
            iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
                @Override
                public void onComplete(List<String> goods) {
                    iGoodsView.get().showGoodsView(goods);
                }

                @Override
                public void onError(String msg) {

                }
            });
        }
    }
}
public class MainActivity extends AppCompatActivity implements IGoodsView {

    private ListView listView;
    GoodsPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);
        presenter = new GoodsPresenter();
        presenter.attachView(this);
        presenter.fetch();
    }
    
    @Override
    public void showGoodsView(List<String> data) {
        listView.setAdapter(new GoodsAdapter(this, data));
    }

    @Override
    public void showErrorMessage(String msg) {

    }

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

进一步优化,抽取BasePresenter

public class BasePresenter<T extends IBaseView> {
    //持有View层的引用
    public WeakReference<T> iGoodsView;


    public void attachView(T view) {
        iGoodsView = new WeakReference<>(view);
    }

    public void detachView() {
        if (iGoodsView != null) {
            iGoodsView.clear();
            iGoodsView = null;
        }
    }
}

简化GoodsPresenter ,非常的简洁

public class GoodsPresenter<T extends IGoodsView> extends BasePresenter {
    //持有Model层的引用
    IGoodsModel iGoodsModel = new GoodsModel();

    public void fetch() {
        if (iGoodsView != null && iGoodsModel != null) {
            iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
                @Override
                public void onComplete(List<String> goods) {
                    ((IGoodsView)iGoodsView.get()).showGoodsView(goods);
                }

                @Override
                public void onError(String msg) {

                }
            });
        }
    }
}

 抽取BaseActivity

public abstract class BaseActivity<T extends BasePresenter, V extends IBaseView> extends AppCompatActivity {

    protected T presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);
        presenter = createPresenter();
        presenter.attachView((V) this);
        registerSDK();
        init();
    }

    protected abstract T createPresenter();

    protected void registerSDK() { }

    protected void unRegisterSDK() { }

    protected void init() { }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.detachView();
        unRegisterSDK();
    }
}

 简化MainActivity

public class MainActivity extends BaseActivity<GoodsPresenter, IGoodsView> implements IGoodsView {

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);
        presenter.fetch();
    }

    @Override
    protected GoodsPresenter createPresenter() {
        return new GoodsPresenter();
    }

    @Override
    public void showGoodsView(List<String> data) {
        listView.setAdapter(new GoodsAdapter(this, data));
    }

    @Override
    public void showErrorMessage(String msg) {

    }

}

基本的MVP架构完成

Jetpack新技术和LifeCycle的融入

LifeCycle是管理生命周期,使用的是一种观察者模式。

Observable被观察者

Activity或者Fragment可以作为被观察者Observable,只要去实现LifecycleOwner接口,就能被别人观察到生命周期。

Observer观察者

任何一个类实现LifecycleObserver接口,就能作为一个观察者,就可以监听到Activity的生命周期。只要Activity的生命周期发生变化,那么UserClass就会收到反馈。

举例说明一下:

public class BasePresenter<T extends IBaseView> implements LifecycleObserver {
    //持有View层的引用
    public WeakReference<T> iGoodsView;


    public void attachView(T view) {
        iGoodsView = new WeakReference<>(view);
    }

    public void detachView() {
        if (iGoodsView != null) {
            iGoodsView.clear();
            iGoodsView = null;
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void abc(LifecycleOwner owner) {

    }
}

只要Activity执行生命周期方法onCreate(),那么abc()方法就会执行.所以只要BasePresenter去实现LifecycleObserver ,那么就可以监听到Activity的生命周期的变化。

接下可以看下可以监听的生命周期方法有下面这些

   @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestory(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onAny(LifecycleOwner owner) {

    }
public class BasePresenter<T extends IBaseView> implements LifecycleObserver {
    //持有View层的引用
    public WeakReference<T> iGoodsView;

    public void attachView(T view) {
        iGoodsView = new WeakReference<>(view);
    }

    public void detachView() {
        if (iGoodsView != null) {
            iGoodsView.clear();
            iGoodsView = null;
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestory(LifecycleOwner owner) {

    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onAny(LifecycleOwner owner) {

    }
    
}

 在GoodsPresenter去复写onCreate()方法和onDestory()方法

public class GoodsPresenter<T extends IGoodsView> extends BasePresenter {
    //持有Model层的引用
    IGoodsModel iGoodsModel = new GoodsModel();

    public void fetch() {
        if (iGoodsView != null && iGoodsModel != null) {
            iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
                @Override
                public void onComplete(List<String> goods) {
                    ((IGoodsView)iGoodsView.get()).showGoodsView(goods);
                }

                @Override
                public void onError(String msg) {

                }
            });
        }
    }

    @Override
    void onCreate(LifecycleOwner owner) {
        super.onCreate(owner);
        Log.i("TAG","onCreate*****");
    }

    @Override
    void onDestory(LifecycleOwner owner) {
        super.onDestory(owner);
        Log.i("TAG","onDestory*****");
    }
}

 因为在AppCompatActivity已经实现LifecycleOwner接口,所以MainActivity不需要再去实现改接口。

调用  getLifecycle().addObserver(presenter)实现绑定

public class MainActivity extends BaseActivity<GoodsPresenter, IGoodsView> implements IGoodsView {

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);
        presenter.fetch();
    }

    @Override
    protected GoodsPresenter createPresenter() {
        return new GoodsPresenter();
    }

    @Override
    public void showGoodsView(List<String> data) {
        listView.setAdapter(new GoodsAdapter(this, data));
    }

    @Override
    public void showErrorMessage(String msg) {

    }

    @Override
    protected void init() {
        super.init();
        getLifecycle().addObserver(presenter);
    }
}

 总结下,使用Lifecycle去监听Activity或者Fragment生命周期的方法。

1、类A 实现接口LifecycleObserver

2、类B  getLifecycle().addObserver(new 类A());

这样实现绑定是不会内存泄漏的。

猜你喜欢

转载自blog.csdn.net/jingerlovexiaojie/article/details/107082729
MVP
今日推荐