Android中简单MVP框架,用来做小项目绰绰有余。

对于很多Android开发人员,在这个浮华的编程世界中,可能大部分人已经习惯了使用普通的MVC框架进行代码的层层堆叠,这样是比较方便当下的编程过程的,但是对于后期可维护性和可扩展性能会造成不可估量的代码重用、层次混乱、耦合性高等一系列问题。比如说:员工A使用相关的Android代码编译了一个正常的、可运行的、性能也基本不受影响的APP项目,但是由于各种原因,最后修改添加功能的需求到了员工B手里面,这样导致了一个问题,员工B需要将员工A之前写过的所有和需要修改代码相关的部分分析和考虑清楚,否则随便添加代码会造成不可估量的损失。

使用MVP框架就会一定程度上的避免这些问题。话不多说,MVP框架的好处在网上一搜一大堆,需要的同学请自行查找。

MVP即Model-View-Presenter的缩写,通过View层调用Presenter层封装的逻辑方法,然后Presenter层会根据相应的标识去Model层中执行相关的任务,最后Model层中的数据再通过回调的方式返回给Presenter层中,这样Presenter就可以调用View层中的UI更新方法把数据传回到用户(View层)的面前。

1.重点是封装Presenter层和Model层的数据传递方法。直接上代码。

LoginActivity:

public class LoginActivity extends BaseActivity implements ILoginActivity {

    private LoginPresenter presenter;
    private StringBuffer pwd;
    
    @override
    protected void onCreate(Bundle saveInstanceState){
        setContentView(R.layout.activity_login);

        presenter = new LoginPresenter(this);
        ...
        
        ...
        

    }
    
    @override
    public abstract void initData(){
        ...
        ...
    };

    @override
    public abstract void initView(){
        ...
        ...
    };

    @override
    public abstract void registerListener(){
        ...
        ...
    };

    @override
    public void onClick(View view){
        //进行登陆前的准备
        presenter.fixData();
        //执行登陆操作
        presenter.login(pwd);
    }

    @override
    public void updateUI(List data){
        //执行更新界面操作
        //如 listview更新数据
    }

}

LoginActivity对应的接口和父类:

BaseActivity:

public abstract class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //做一些所有activity共有的操作
        initData();
        initView();
        registerListener();
    }

    /**
     * 初始化数据
     */
    public abstract void initData();

    /**
     * 初始化布局
     */
    public abstract void initView();

    /**
     * 注册监听器
     */
    public abstract void registerListener();


}

ILoginActivity:

public interface ILoginActivity {
    
   void updateUI(Object data);//更新界面

}

 

BasePresenter:

public abstract class BasePresenter implements UIEventListener {
    private BaseActivity context;

    protected BasePresenter(BaseActivity context){
        this.context=context;
        BaseCore.getInstance().registerUIEventListener(this);
    }
    //********************************* 接口函数 *********************************
    @Override
    public void onUIEventListener(final int event, final Object data) {
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                handleUIEvent(event,data);
            }
        });
    }
    //********************************* 其它函数 *********************************

    /**处理UI事件
     * @param event 事件标识
     * @param data 数据
     */
    protected abstract void handleUIEvent(int event,Object data);
    public void removeUilistener(){
        BaseCore.getInstance().removeUIEventListener(this);
    }
}

LoginActivity对应的LoginPresenter:

public class LoginPresenter extends BasePresenter {
    private ILoginActivity loginActivity;
    private Context context;

    public LoginPresenter(ILoginActivity loginActivityView) {
        super(context);
        this.loginActivity = loginActivityView;
        this.context = context;
    }

    public void login(StringBuffer pwd) {
        //调用Model层执行任务的方法
        BaseCore.getInstance().postCoreEventAtFirst(CoreEvent.CORE_EVENT_LOGIN, pwd);
    }

    @Override
    protected void handleUIEvent(int event, Object data) {//Model层回调执行的方法
        switch (event) {
            case CoreEvent.CORE_EVENT_LOGIN://标识Model层传回的数据  
                //执行登陆成功的操作 
                //例如
                ILoginActivity.updateUI(data);                     
                break;
            case CoreEvent.CORE_UI_NET_EXCEPTION:
                Log.e("TAG","网络异常,请检查网络!");
                break;
    }
}

CoreEvent://分发的任务事件和更新UI标识 

public class CoreEvent {
    public static final int CORE_EVENT_LOGIN = 1010;//用来执行登陆任务
    public static final int CORE_UI_LOGIN = 1011;//用来更新登录界面
}  

BaseCore://事件分发总线

public class BaseCore {
    private static BaseCore baseCore;
    private TaskCore mTaskCore;
    private ArrayList uiEventListenersList = new ArrayList<>(8);//UI监听器集合
    private ArrayList> waitRequestList = new ArrayList<>(5);//等待与接口通信的请求

    public static BaseCore getInstance() {
        if (baseCore == null) {
            baseCore = new BaseCore();
        }

        return baseCore;
    }

    private BaseCore() {
        mTaskCore = new TaskCore(this);
        
    }

    /**
     * 分发事件
     *
     * @param event 事件标识
     * @param data  数据
     */
    public void postCoreEvent(int event, Object data) {
        mTaskCore.postCoreEvent(event, data);
       
    }

    /**
     * 分发事件-立即
     *
     * @param event 事件标识
     * @param data  数据
     */
    public void postCoreEventAtFirst(int event, Object data) {
        mTaskCore.postCoreEventAtFirst(event, data);
       
    }

    /**
     * 分发事件-延时
     *
     * @param event     事件标识
     * @param data      数据
     * @param delayTime 延时时间 ms
     */
    public void postCoreEventDelay(int event, Object data, long delayTime) {
        mTaskCore.postCoreEventDelay(event, data, delayTime);
       
    }

    /**
     * 分发更新UI事件
     *
     * @param event 事件
     * @param data  数据
     */
    public void notifyUIEvent(int event, Object data) {
        if (uiEventListenersList != null) {
            for (int i=uiEventListenersList.size()-1;i>=0;i--){
                uiEventListenersList.get(i).onUIEventListener(event,data);
            }
        }
    }

    /**
     * 注册UI监听器
     *
     * @param uiEventListener
     */

    public void registerUIEventListener(UIEventListener uiEventListener) {
        if (uiEventListener != null && uiEventListenersList != null && !uiEventListenersList.contains(uiEventListener)) {
            uiEventListenersList.add(uiEventListener);
        }
    }

    /**
     * 移除UI监听器
     *
     * @param uiEventListener
     */
    public void removeUIEventListener(UIEventListener uiEventListener) {
        if (uiEventListener != null && uiEventListenersList != null && uiEventListenersList.contains(uiEventListener)) {
            uiEventListenersList.remove(uiEventListener);
        }
    }

    public void addWaitRequest(int event, Object data) {
        HashMap waitRequestMap = new HashMap<>();
        waitRequestMap.put(event, data);
        for (HashMap map : waitRequestList) {
            if (map.containsKey(event)) {
                waitRequestList.remove(map);
                break;
            }
        }
        waitRequestList.add(waitRequestMap);
        LogUtils.wtf(waitRequestList);
    }

    public void removeWaitRequest(int event) {
        for (HashMap map : waitRequestList) {
            if (map.containsKey(event)) {
                waitRequestList.remove(map);
                break;
            }
        }
    }

    public void doWaitRequest() {
        LogUtils.wtf(waitRequestList);
        for (HashMap map : waitRequestList) {
            Iterator iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                Integer event = (Integer) entry.getKey();
                Object data = entry.getValue();
                BaseCore.getInstance().postCoreEvent(event, data);
            }
        }
    }
}

UIEventListener://UI监听回调接口

public interface UIEventListener {
    /**
     * UI监听器回调
     * @param event 事件标识
     * @param data 数据
     */
    public void onUIEventListener(int event, Object data);
}

EventHandler://执行分发事件和处理数据线程的工具类

public abstract class EventHandler {
    private Handler handler;
    protected HandlerThread handlerThread;
    protected EventHandler(){
        handlerThread=new HandlerThread(this.getClass().getSimpleName());
        handlerThread.start();
        handler=new Handler(handlerThread.getLooper()){
            @Override
            public void handleMessage(Message msg) {
                handleCoreEvent(msg.what,msg.obj);
            }
        };
    }

    /** 处理事件 重写并实现具体事件处理逻辑
     * @param event 事件标识
     * @param data 数据
     */
    protected abstract void handleCoreEvent(int event,Object data);

    /**
     * 发布事件-立即
     * @param event
     * @param data
     */
    protected void postCoreEventAtFirst(int event,Object data){
        Message msg= Message.obtain();
        msg.what=event;
        msg.obj=data;
        handler.sendMessageAtFrontOfQueue(msg);
    }

    /**
     * 发布事件-延时
     * @param event 事件标识
     * @param data 数据
     * @param delayTime 延时时间
     */
    protected void postCoreEventDelay(int event, Object data, long delayTime){
        Message msg= Message.obtain();
        msg.what=event;
        msg.obj=data;
        handler.sendMessageDelayed(msg,delayTime);

    }

    /**
     * 发布事件
     * @param event
     * @param data
     */
    protected void postCoreEvent(int event,Object data){
        Message msg= Message.obtain();
        msg.what=event;
        msg.obj=data;
        handler.sendMessageAtFrontOfQueue(msg);

    }
    public Handler getHandler(){
        return handler;
    }
}

TaskCore://执行任务和数据生成的线程

public class TaskCore extends EventHandler {
    private BaseCore mBaseCore;

    public TaskCore(BaseCore baseCore){
        this.mBaseCore = baseCore;
    }

    @override
    protected void handlerCoreEvent(int event,Object data){
        switch (event) {
            case CoreEvent.CORE_EVENT_LOGIN:
            //处理登陆操作,即请求接口
            //此处是子线程,可以进行耗时操作
            login(data);
            
        }


    }

    private void login(data){
        //...

        //...
        //接口调用成功将数据返回到presenter层
          mBaseCore.notifyUIEvent(CoreEvent.CORE_UI_LOGIN, list);  //list即接口返回数据

    }
}

对于EventHandler中的handler对象,可以直接传递到OkHttp中,然后可以根据handler来判断数据需要返回的线程。具体操作就参考OkHttp使用说明中Request.Build()中的使用。

总结:该框架主要适合小一些的项目是用,因为本人没有测试过在大型项目上的使用情况。在本地使用的项目中,涉及到添加功能和修改代码的时候逻辑会相当清晰,并且记住某几个点需要修改就OK了。声明:MVP框架是搭建的时候稍微复杂一些的框架,但是后期维护和修改比较方便,具体需不需要使用请各位具体就情况而定。

原创不易,请大家点赞分享。

个人微信号:cai-niao-bu-ke-yi;新浪微博:prince-or-king;qq:1125325256,欢迎大家私信。

你可能感兴趣的:(Android项目MVP框架)