首页后端开发其他后端知识关于Android中 MVP框架的原理你知道多少?

关于Android中 MVP框架的原理你知道多少?

时间2024-03-28 15:18:03发布访客分类其他后端知识浏览302
导读:这篇文章给大家分享的是“关于Android中 MVP框架的原理你知道多少?”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“关于Android中 MVP框架的原理你知道...
这篇文章给大家分享的是“关于Android中 MVP框架的原理你知道多少?”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“关于Android中 MVP框架的原理你知道多少?”吧。

在Android项目中,按照MVC的分层,Activity和Fragment应该属于View层,用于展示UI界面,以及接收用户的输入,此外还要承担一些生命周期的工作。所以开发的时候我们经常把一些业务逻辑直接写在Activity里面,这非常直观方便,代价就是Activity会越来越臃肿,而在Activity中,把View和Controller抽离开来,而这就是MVP模式的工作了。

MVP模式的核心思想

MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model。这就是MVP模式,现在这样的话,Activity的工作的简单了,只用来响应生命周期,其他工作都丢到Presenter中去完成。从上图可以看出,Presenter是Model和View之间的桥梁,为了让结构变得更加简单,View并不能直接对Model进行操作,这也是MVP与MVC最大的不同之处。


MVP模式的作用

  1. 分离了视图逻辑和业务逻辑,降低了耦合
  2. Activity只处理生命周期的任务,代码变得更加简洁
  3. 视图逻辑和业务逻辑分别抽象到了View和Presenter的接口中去,提高代码的可阅读性
  4. Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单元测试
  5. 把业务逻辑抽到Presenter中去,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露和OOM


应用举例

在这里使用一个在ListView中更新适配器数据的例子来简单说明MVP模式是怎么使用的。


1.项目结构

在这里,颜色标注的即是我们用到的


2. model层

使用的是GsonFormat插件自动生成的bean,因此model层不需要关注bean,但由于使用了Retrofit Rxjava。

PS:使用Retrofit是因为可以很简单处理异步请求,而使用Rxjava是因为可以将被观察者跟观察者的调度任务自动切换io跟ui线程。 因此,在model层,只需要关心manager怎么组织即可。

public class DataManager {
    
    private RetrofitService mRetrofitService;


    public DataManager(){
    
        this.mRetrofitService = RetrofitHelper.getInstance()
                .getRetrofit("http://api.douban.com/v2/").getServer();

    }


    public ObservablegetDoubanInfo(){
    
        return mRetrofitService.getInTheaters();

    }

}


3. present层

present就是用来处理所有业务逻辑工作的代理层,假设我们在Activity/Fragment中可以把工作丢给present来处理,那会有哪些方法呢?


更新上映电影的数据

提供页面跳转时的方法 于是就有了IDoubanPresenter这个接口

public interface IDoubanPresenter {
    
    void updateInTheaters();
    
    void reachDetail();

}


那么它的实现则为

public class DoubanPresenter implements IDoubanPresenter {
    

    private DataManager dataManager;
    
    private CompositeSubscription mCompositeSubscription;
    
    private IDoubanView mIDoubanView;
    
    private int index;
    
    public Douban mDouban;


    public DoubanPresenter (IDoubanView view){
    
        this.mIDoubanView = view;
    
        dataManager = new DataManager();
    
        mCompositeSubscription = new CompositeSubscription();

    }


    public void onStop() {

        if (mCompositeSubscription.hasSubscriptions()){
    
            mCompositeSubscription.unsubscribe();

        }

    }


    @Override
    public void updateInTheaters(){

        mCompositeSubscription.add(dataManager.getDoubanInfo()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer(){

                    @Override
                    public void onCompleted() {

                        if (mDouban != null){
    
                            mIDoubanView.updateInTheaters(mDouban);

                        }

                    }


                    @Override
                    public void onError(Throwable e) {
    
                        e.printStackTrace();

                    }


                    @Override
                    public void onNext(Douban douban) {
    
                        mDouban = douban;

                    }

                }
    )
        );

    }


    @Override
    public void reachDetail(){

        mCompositeSubscription.add(dataManager.getDoubanInfo()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer(){

                    @Override
                    public void onCompleted() {

                        if (mDouban != null){
    
                            mIDoubanView.enterDetail(mDouban, index);

                        }

                    }


                    @Override
                    public void onError(Throwable e) {
    
                        e.printStackTrace();

                    }


                    @Override
                    public void onNext(Douban douban) {
    
                        mDouban = douban;

                    }

                }
    )
        );

    }


}


在Present中可以看到,我们持有dataManager跟view的实例,因为业务逻辑都在这里处理,dataManager用来处理数据很好理解,view在这里不做真正的操作,只是执行一个接口方法,剩下的在接口实现里完成。


4. view层

view层其实就是我们的Activity或者Fragment。在使用List更新豆瓣接口数据,UI操作需要的方法有

  1. 更新上映电影的View
  2. 页面跳转时的方法
  3. 异常时怎么显示 于是就有了IDoubanView这个接口
public interface IDoubanView {
    
    void updateInTheaters(Douban mDouban);
    
    void enterDetail(Douban mDouban, int index);
    
    void onError(String result);

}


然后我们在Fragment中实现这个接口

public class DoubanFragment extends Fragment implements IDoubanView {
    

    private ListView listView;
    
    private DoubanItemAdapter mAdapter;
    
    private DoubanPresenter mDoubanPresenter;


    @Nullable
    @Override
    public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
    
        View view = inflater.inflate(R.layout.card_fragment, container, false);
    
        listView = view.findViewById(R.id.card_listview);
    
        mDoubanPresenter = new DoubanPresenter(this);
    
        mDoubanPresenter.updateInTheaters();

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView adapterView, View view, int i, long l) {
    
                mDoubanPresenter.reachDetail();

            }

        }
    );
    
        return view;

    }



    @Override
    public void updateInTheaters(Douban mDouban) {
    
        mAdapter = new DoubanItemAdapter(getActivity(), mDouban.getSubjects());
    
        listView.setAdapter(mAdapter);
    
        mAdapter.notifyDataSetChanged();

    }


    @Override
    public void enterDetail(Douban mDouban, int index) {
    
        Intent mIntent = new Intent(getActivity(), WebActivity.class);
    
        mIntent.putExtra("url", mDouban.getSubjects().get(index).getAlt());
    
        startActivity(mIntent);

    }


    @Override
    public void onError(String result) {


    }

}
    


其中updateInTheaters跟enterDetail这两个接口方法由prisent调用实现。所以这个链路变成Activity/Fragment(移交任务) -> Present(数据处理) -> Activity/Fragment(渲染view)。


关于“关于Android中 MVP框架的原理你知道多少?”的内容就介绍到这,感谢各位的阅读,相信大家对关于Android中 MVP框架的原理已经有了进一步的了解。大家如果还想学习更多知识,欢迎关注网络,小编将为大家输出更多高质量的实用文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: 关于Android中 MVP框架的原理你知道多少?
本文地址: https://pptw.com/jishu/655024.html
Bootstrap Table怎么实现拖拽改变列宽的功能 JavaScript中数组对象排序的方法是什么

游客 回复需填写必要信息