简单实现android中MVP架构

如果还不知道MVP是什么,请自行google了,我这里是简单实现MVP的框架,就是将Activity,或Fragment复制一份,真正的Activity、fragment负责V层,复制的Activity、Fragment充当P层。我们先看看代码,分析下是如何封装的,以便于我们充分理解后进行扩展


复制Activity其实就是让我们的presenter实现BasePresenterInterface接口,实现activity各个生命周期的方法,然后在Activity的生命周期中调用这些方法,这样presenter看上去就像一个Activity了,有点像包装设计模式,持有一个真正Activity的引用

BasePresenterInterface:

    public interface BasePresenterInterface {
    
        void onCreate(Bundle bundle);
        
        void onStart();
        
        void onResume();
        
        void onPause();
        
        void onDestroy();
        
        void onStop();
    }

复制Activity:

    /**
     * Created by zhangy on 2016/4/15.
     * <p/>
     * des : 将presenter与UI层绑定
     */
    public abstract class BaseMVPActivity<T extends BasePresenter<U>, U extends BaseUI> extends FragmentActivity {//泛型控制,保证每个V层都有对应的P层
        //要绑定的Presenter,每个Activity都会有一个与自己对应的Presenter
        private T mPresenter;
    
        protected abstract T createPresenter();
        //这里的U是一个接口,定义了我们要返回的UI,例如,activity中有ListView,fragment,TextView等等,我们如果想暴露给外面,可以在这个接口中声明
        protected abstract U getUi();
    
        public T getPresenter() {
            return mPresenter;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mPresenter = createPresenter();//创建Presenter
            mPresenter.onUiReady(getUi(), this);//给 P 层传递我们的 V 层(MVP)
            mPresenter.onCreate(getIntent().getExtras());
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            mPresenter.onStart();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            mPresenter.onUiDestroy(getUi());
            mPresenter.onDestroy();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            mPresenter.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            mPresenter.onPause();
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            mPresenter.onStop();
        }
    }

请注意到我们在BaseMVPActivity中我们重写了Activity的生命周期方法,并调用presenter对应的方法,这相当于又复制出一个Activity,以后我们就可以像使用Activity一样使用presenter

从类名我们看到,在创建Activity的时候就必须创建一个与之对应的presenter,UI接口。这样我们的Activity只负责UI的显示,对应的presenter负责具体的业务逻辑,与数据交互,通过BaseUI接口暴漏Activity的成员变量,指定Activity的特殊展示。

BasePresenter:


    /**
     * Created by zhangy on 2016/4/15.
     */
    public class BasePresenter <U extends BaseUI> implements BasePresenterInterface {
    
        /**
         * 是否是Fragment 备用
         */
        private boolean mIsFragment;
        /** 绑定的V层,有可能是Activity、Fragment */
        private U mUi;
    
        private Activity mActivity;
    
        private Fragment mFragment;
    
        public BasePresenter(boolean isFragment){
            super();
            mIsFragment = isFragment;
        }
        /** 在Fragment中绑定的V层 */
        public void onFragmentAttach(Activity activity, Fragment fragment) {
            mActivity = activity;
            mFragment = fragment;
        }
        /** 绑定Activity */
        public void onUiReady(U ui,Activity activity) {
            mUi = ui;
            mActivity = activity;
        }
    
        /**
         * @author :zhangy
         *
         * @description : 在UI销毁时调用
         *
         *  DATE : 2016/4/15
         */
        public final void onUiDestroy(U ui) {
            onUiUnready(ui);
            mUi = null;
        }
    
        public U getUi() {
            return mUi;
        }
    
        public Activity getActivity() {
            return mActivity;
        }
    
        public Fragment getFragment() {
            return mFragment;
        }
    
        /**
         * @author :zhangy
         *
         * @description : 当Fragment或者Activity即将被销毁时调用,可用于取消监听事件、取消注册事件
         *
         *  DATE : 2016/4/15
         */
        public void onUiUnready(U ui) {
        }
    
        // 默认空实现Activity生命周期
        @Override
        public void onCreate(Bundle bundle) {
    
        }
    
        @Override
        public void onStart() {
    
        }
    
        @Override
        public void onResume() {
    
        }
    
        @Override
        public void onPause() {
    
        }
    
        @Override
        public void onDestroy() {
    
        }
    
        @Override
        public void onStop() {
    
        }
    }

在BasePresenter中主要是实现Activity、Fragment生命周期的方法,绑定V层。具体的业务由子类根绝UI接口扩展添加

我们看下BaseUI接口:

    public interface BaseUI {

        ListView getListView();//这里我只是举个例子,不一定每个页面都有listView
    }

使用方法很简单,在我们创建Activity时继承BaseMVPActivity,并创建对应的presenter,UI接口即可。例如我创建的Demo

    public class MainActivity extends BaseMVPActivity<MainPresenter, MainUI> implements MainUI {

        private ListView mListView;
        private MainPresenter mainPresenter;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mListView = (ListView) findViewById(R.id.list_view);
            loadData();
        }
    
        @Override
        public void loadData() {
            mainPresenter.loadData();
        }
    
        @Override
        protected MainPresenter createPresenter() {
            mainPresenter = new MainPresenter(false);
            return mainPresenter;
        }
    
        @Override
        protected MainUI getUi() {
            return this;
        }
    
    
        @Override
        public ListView getListView() {
            return mListView;
        }
    }

我们再来看下怎么实现presenter层,它又干了什么

    public class MainPresenter extends BasePresenter<MainUI> {
        /** Mode层管理类 */
        private FrontMode frontMode;
    
        public MainPresenter(boolean isFragment) {
            super(isFragment);
            frontMode = new FrontMode();//创建一个Mode层管理类
        }
    
        public void loadData() {
            /** 让Mode管理层去处理数据的请求,解析,我们只处理回调 */
            frontMode.requestData(getActivity(), new RequestListener() {
                @Override
                public void onSucces(List datas) {
                    setDatas(datas);
                }
                @Override
                public void onFail() {
    
                }
            });
        }
        /**
         * author : zhangy
         *
         * des : 给V层加载数据
         *
         * date : 2016/5/5
         */
        private void setDatas(List datas) {
            getUi().getListView().setAdapter(new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, datas));
        }
    }

在presenter层我们把具体的业务逻辑分离出来,将V层与M层解耦。再看下M层

    /**
     * Created by zhangy on 2016/5/5.
     * <p/>
     * MVP中的M层,处理网络请求,数据解析、数据封装,与Bean、presenter交互
     */
    public class FrontMode {
        /**
         * author : zhangy
         * <p/>
         * des : 这里的数据请求可以换成volley、okHttp.
         * <p/>
         * date : 2016/5/5
         */
        public List requestData(final Activity activity, final RequestListener listener) {
            final ArrayList datas = new ArrayList();
            //模拟数据请求
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    SystemClock.sleep(2000);//模拟耗时
                    datas.add("pfg");
                    datas.add("124");
                    datas.add("234");
                    datas.add("456");
                    datas.add("567");
    
                    if (datas.isEmpty()) {
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.onFail();
                            }
                        });
                    } else {
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.onSucces(datas);
                            }
                        });
                    }
                }
            }).start();
            return datas;
        }
    }

    //回调接口
    public interface RequestListener {
    
       void onSucces(List datas);
    
        void onFail();
    }

所有的数据相关的处理都放在FrontMode统一管理。这里我用的是线程模拟数据请求,大家可以继承喜欢的网络框架。

通过上面的框架我们就简单的实现了MVP模型,以后代码的管理维护更简单,思路清晰,分工明确。


感兴趣的童鞋可以到我的github上下载。记得star下(!_!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容