在讲解GoMVP框架的使用以前,咱们先了解一下什么是AOP。android
AOP —— Aspect Oriented Program,即面向切面编程,面向切面编程是一种思想,如同面向对象编程同样,都是思想。编程
主工程中gradle添加:api
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.2'
}
}
复制代码
app工程中gradle:缓存
apply plugin: 'com.android.application'
apply plugin: 'android-aspectjx'
复制代码
app添加GoMVP依赖:网络
dependencies {
implementation 'com.wookii.gomvp:gomvp:1.3.2'
}
复制代码
app添加AOP配置:架构
android{
aspectjx {
//AOP时,排除全部package路径中包含`android.support`的class文件及库(jar文件)
exclude 'android.support'
}
}
复制代码
public class AnnotationDemoActivity extends AppCompatActivity {
@BindView(R.id.button2)
Button button;
@BindView(R.id.button3)
Button button3;
@DataSource(RepositoryInjection.class)
private LifecyclePresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_demo);
}
/**
* test @GoBack
* @param bean
*/
@GoBack
public void hahaha(MarketBean bean) {
GoLog.E("MarketBean is backing:" + bean.getMessage());
}
@GoError
public void error(String errorMsg) {
GoLog.E("error is backing:" + errorMsg);
}
@OnClick({R.id.button2, R.id.button3})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button2:
break;
case R.id.button3:
presenter.execute(new MarketPresenterAdapter());
break;
}
}
}
复制代码
也许目前这个Demo片断你们看起来难以消化,从它的一些注解能猜想到这是一个基于注解以及AOP实现的MVP框架,那么接下来咱们一步步拆分,还原,介绍GoMVP的使用。app
GoMVP的网络请求框架是基于Retrofit,RxJava,OkHttp的网络框架,为了框架的灵活性,框架自己并不包含Retrofit的建立,这个须要外部提供,也就是使用者本身的Retrofit。建立好后,留着待用。框架
public class MainRetrofit implements RetrofitConverter {
@Override
public String host() {
return ApiServer.URL_CONTRACT_NET;
}
@Override
public Retrofit createRetrofit() {
return XstoreRetrofitManager.getInstance().getRetrofit(host(), null);
}
}
复制代码
首先实现RetrofitConverter类,实现的第一个方法是指定网络请求的host,第二个方法建立一个Retrofit而且create。这里的XstoreRetrofitManager是使用者本身的。ide
在MVP架构中,数据仓库是必不可少的组件(Repository),咱们先来建立它。post
public class MarketRepository implements GoDataSource {
@Override
public <B> GoDataSource loadDataFromRepository(Observable<B> observable, Observer observer) {
observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
return this;
}
@Override
public GoCache getGoCache(Context context) {
return new DefaultGoCache(context);
}
//绑定RetrofitConverter,很是关键
@Override
public RetrofitConverter onCreateRetrofitConverter() {
return new MainRetrofit();
}
@Override
public <T> void targetClazz(Class<T> clazz) {
return MarketBean.class;
}
}
复制代码
做为使用了GoMVP的Repository,必须实现GoDataSource接口,这个接口返回了四个方法功能以下:
一、loadDataFromRepository方法:
当presenter发起操做时,这是核心方法,治理返回了观察者和被观察者,发挥你的想象力能够在这里作一些业务逻辑的处理
二、getGoCache方法:
使用者须要在这里返回一个缓存对象,默认使用由框架DefaultGoCache,后面会对缓存的扩展进行讲解。
三、onCreateRetrofitConverter方法:
最为关键,这个方法里返回的就是咱们第二步建立的MainRetrofit对象,这样数据仓库和具体的Retrofit进行了绑定。
四、targetClazz方法:
会接收到一个class对象,这个class对象一般状况下是个JavaBean,这是由使用者 去指定的,指定的地方在Presenter中,有些时候请求返回的Bean并非咱们想要的,能够经过指定的bean作业务上的强转,仍是看具体业务你用不用的上了。
在传统的设计中Presenter的扩展都是经过继承来完成的,在GoMVP中摒弃了这样的方式,是经过PresenterAdapter去进行扩展(若是看到这里比较迷糊,下一先跳过这一部分看一下示例再反过头来看这部份内容)。
public class MarketPresenterAdapter extends PresenterAdapter{
@Override
public Observable onCreateObservable(Context context, RetrofitConverter retrofitConverter) {
Retrofit retrofit = retrofitConverter.createRetrofit();
ApiServer apiServer = retrofit.create(ApiServer.class);
HashMap<String, Object> map = new HashMap<>();
map.put("请求参数1",0);
map.put("请求参数2","123");
Observable<HttpResult<SecretKeyBean>> observable = apiServer.getSecretKey(map);
return observable;
}
@Override
public Pair onSuccessCodePair() {
return new Pair("success","true");
}
@Override
public String onErrorMessageKey() {
return "message";
}
@Override
public Class targetBeanType() {
return MarketBean.class;
}
}
复制代码
依旧是四个方法,咱们分别解读一下他们的做用
一、onCreateObservable方法:
该方法须要咱们建立一个Observable对象,这个对象会在咱们第三步建立的Repostory里返回,方法体提供了一个RetrofitConverter对象,用来建立Observable,而这个RetrofitConverter是咱们第二步建立出来,第三部绑定的。
二、targetBeanType方法
这个方法很关键,上面说到Repository的targetClazz方法会返回一个class,就是由这个方法指定的,除此以外它还有个更关键的功能,我下面再说。
其余两个onSuccessCodePair和onErrorMessageKey方法如今用不到,后面再讲。
前面准备了怎么多,咱们开始使用。
/**
* Demo
*/
public class AnnoDemoActivity extends AppCompatActivity{
@BindView(R.id.button2)
Button button;
@BindView(R.id.button3)
Button button3;
@Presenter()
private LifecyclePresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_demo);
//绑定数据仓库
presenter.setRepository(new MarketRepository());
}
@GoBack
public void hahaha(MarketBean bean) {
GoLog.E("MarketBean is backing:" + bean.getValue().getMarketData().getAmountRtv());
}
@GoError
public void error(String errorMsg) {
GoLog.E("error is backing:" + errorMsg);
}
@OnClick({R.id.button2, R.id.button3})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button2:
presenter.execute(new MarketPresenterAdapter());
break;
case R.id.button3:
break;
}
}
}
复制代码
一、任意一个类型为LifecyclePresenter 的成员变量加上@Presenter注解,在Activity的onCreate时就会被建立好。
@Presenter
private LifecyclePresenter presenter;
复制代码
PS:之因此叫作LifecyclePresenter,是由于它具备生命周期感知功能,无需使用者关心生命周期的问题,好比释放Presenter,同时它内部集成了BKnife,默认会管理BKnife的初始化与解除绑定等与生命周期相关的操做(使用者在本身的工程添加BKnife的依赖便可)。
二、在onCreate中绑定数据仓库
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_demo);
//绑定数据仓库
presenter.setRepository(new MarketRepository());
}
复制代码
经过new的方式初始化MarketRepository是不优雅的,不建议这样作,真正的作法是使用RepositoryInjection:下一节见。