一些水话
这是我写的第一篇博客,姑且是对自己学习android的总结吧,自2015年在大三上学期开始自学android,到现在即将步入职场,已经过去了整整一年有余,就写下一些希望对自己和别人有用的东西吧!博客以后会不定期的更新有关于Java和android语言的知识,欢迎大家留言斧正.
MVP模式
MVP模式可以分离显示层和逻辑层,它们之间通过接口进行通信.
假设Activity既负责显示数据又负责获取数据,耦合性太高,导致我们在日后假如要修改UI(V层),还要涉及到对原来的业务逻辑的抽离,如果使用了MVP模式,我们不需要担心这个问题,而且可以对独立的各个模块进行单元测试,
Activity负责显示数据
获取数据的任务交给Presenter(方法为:调用Presenter的方法>>load),不负责获取数据.
Presenter请求数据
获取的方式:交给M层(业务逻辑层)
在MainActivityPresenter类中调用了来自MvpModelInter接口的抽象方法,由于MainActivityModel已经调用了实现了该类,所以必须要重写该方法在这个方法中获取了数据后调用MvpModelInter中的一个监听接口OnLoadCompleteListener
的onLoadComplete
方法
@Override
public void getData(OnLoadCompleteListener onLoadCompleteListener) {
// 获取数据
getDataList(list);
// 该回调方法会把数据传递出去,Presenter会重写这个方法
// 用接口回调, 要么通过构造方法传过来一个接口对象,要么参数传递过来
// 谁传过来?->P层,本例中没有从View层中传递过来的引用
onLoadCompleteListener.onLoadComplete(list);
}
private void getDataList(List<String> list) {
for (int i = 0; i < 100; i++) {
list.add("这是MVP 创建的数据" + i);
}
}
Presenter获取请求到的数据
model获取完之后怎么把数据传回来?
回调接口MvpModelInter的getData方法>>mvpModel.getData(要调用这个方法必须要在括号里重写监听接口的抽象方法);
mvpModel.getData(new MvpModelInter.OnLoadCompleteListener() {
@Override
public void onLoadComplete(List<String> list) {
//获取到来自M层的数据>List<String> list
//回调来自V层的方法,并传入要传递的数据,这个方法会在Activity中被重写
mvpView.showView(list);
}
});
这样最终数据会传递到Presenter中
Presenter的构造方法中实现了MvpModelInter的类
MainActivityModel:
public MainActivityPresenter(MvpViewInter mvpView) {
this.mvpView = mvpView;
mvpModel = new MainActivityModel();//----------这里
}
然后由Presenter再想办法通知activity>告诉的方式
因为MainActivity实现了MvpViewInter接口
MainActivity extends Activity implements MvpViewInter
在调用请求获取数据的时候有这样一条语句
MainActivity中:
new MainActivityPresenter(MainActivity.this).load();
MainActivityPresenter中
public MainActivityPresenter(MvpViewInter mvpView) {
this.mvpView = mvpView;//----------这里
mvpModel = new MainActivityModel();
}
因此Presenter的构造方法在调用的时候已经创建了一个MvpViewInter对象,
此时我们通过调用对应的接口方法把数据传给 MainActivity,然后MainActivity因为实现了MvpViewInter接口重写了showView
我们在showView方法中更新数据即可
代码由三个类
MainActivity
package com.example.mvpfirststep;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.mvpfirststep.view.MvpViewInter;
import com.example.presenter.MainActivityPresenter;
public class MainActivity extends Activity implements MvpViewInter {
private ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.lv_listview);
// Activity 只能展示数据
// 需要Presenter获取数据>调用Presenter的方法>>MainActivityPresenter(MvpViewInter mvpView).load
new MainActivityPresenter(MainActivity.this).load();
}
/**
* 获取到数据>>更新界面
*
* @param list
*/
@Override
public void showView(List<String> list) {
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, list);
mListView.setAdapter(adapter);
}
}
MainActivityPresenter
package com.example.presenter;
import java.util.List;
import com.example.model.MainActivityModel;
import com.example.model.MvpModelInter;
import com.example.mvpfirststep.view.MvpViewInter;
public class MainActivityPresenter {
private MvpModelInter mvpModel;
private MvpViewInter mvpView;
public MainActivityPresenter(MvpViewInter mvpView) {
this.mvpView = mvpView;
mvpModel = new MainActivityModel();
}
public void load() {
mvpModel.getData(new MvpModelInter.OnLoadCompleteListener() {
@Override
public void onLoadComplete(List<String> list) {
// 获取到来自M层的数据>List<String> list
// 回调来自V层的方法,并传入要传递的数据,这个方法会在Activity中被重写
mvpView.showView(list);
}
});
}
}
MainMvpModel
package com.example.model;
import java.util.ArrayList;
import java.util.List;
// Model 业务逻辑层
public class MainActivityModel implements MvpModelInter {
private List<String> list = new ArrayList<>();
@Override
public void getData(OnLoadCompleteListener onLoadCompleteListener) {
// 获取数据
getDataList(list);
// 该回调方法会把数据传递出去,Presenter会重写这个方法
// 用接口回调, 要么通过构造方法传过来一个接口对象,要么参数传递过来
// 谁传过来?->P层,本例中没有从View层中传递过来的引用
onLoadCompleteListener.onLoadComplete(list);
}
private void getDataList(List<String> list) {
for (int i = 0; i < 100; i++) {
list.add("这是MVP 创建的数据" + i);
}
}
}
两个接口
MvpView
package com.example.mvpfirststep.view;
import java.util.List;
public interface MvpViewInter {
void showView(List<String> list);
}
MvpModel
package com.example.model;
import java.util.List;
public interface MvpModelInter {
void getData(OnLoadCompleteListener listener);
public interface OnLoadCompleteListener {
void onLoadComplete(List<String> list);
}
}
至于布局文件相当简单,就一个activity_main放了一个ListView
文档目录如下:
总结
想要基本使用MVP模式,必须对接口回调具有深入的理解,建议在这方面还有理解困难的同学可以使用Viso画出一个思维导图,顺便向大家推荐一款不错的软件:XMind,这款软件可以用来画出很漂亮的思维导图,帮助大家理清思路
下一个部分我准备写一篇关于在MVP中使用虚引用的博客,需要用到的知识点有接口回调,泛型,大家也可以想想为什么使用虚引用,这样做有什么好处?