MVP与Jetpack组合应用

    技术2022-07-14  88

    搭建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的时候回收弱引用,为了使回收的动作更快一点,可以采用绑定/解绑的方式。

    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());

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

    Demo地址

    Processed: 0.014, SQL: 9