对于很多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,欢迎大家私信。