博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于AOP的MVP框架(一)GoMVP的使用
阅读量:6230 次
发布时间:2019-06-21

本文共 6407 字,大约阅读时间需要 21 分钟。

什么是AOP?

在讲解GoMVP框架的使用之前,我们先了解一下什么是AOP。

面向切面编程

AOP —— Aspect Oriented Program,即面向切面编程,面向切面编程是一种思想,如同面向对象编程一样,都是思想。

一、GoMVP的使用

1、添加依赖与插件

主工程中gradle添加:

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'    }}复制代码

Demo

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的使用。

2、初始化Retrofit

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是使用者自己的。

3、初始化数据仓库

在MVP架构中,数据仓库是必不可少的组件(Repository),我们先来创建它。

public class MarketRepository implements GoDataSource {    @Override    public  GoDataSource loadDataFromRepository(Observable 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 
void targetClazz(Class
clazz) { return MarketBean.class; }}复制代码

作为使用了GoMVP的Repository,必须实现GoDataSource接口,这个接口返回了四个方法功能如下:

1、loadDataFromRepository方法:

当presenter发起操作时,这是核心方法,治理返回了观察者和被观察者,发挥你的想象力可以在这里做一些业务逻辑的处理

2、getGoCache方法:

使用者需要在这里返回一个缓存对象,默认使用由框架DefaultGoCache,后面会对缓存的扩展进行讲解。

3、onCreateRetrofitConverter方法:

最为关键,这个方法里返回的就是我们第二步创建的MainRetrofit对象,这样数据仓库和具体的Retrofit进行了绑定。

4、targetClazz方法:

会接收到一个class对象,这个class对象通常情况下是个JavaBean,这是由使用者 去指定的,指定的地方在Presenter中,有些时候请求返回的Bean并不是我们想要的,可以通过指定的bean做业务上的强转,还是看具体业务你用不用的上了。

4、创建Presenter扩展

在传统的设计中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
map = new HashMap<>(); map.put("请求参数1",0); map.put("请求参数2","123"); Observable
> 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; }}复制代码

依旧是四个方法,我们分别解读一下他们的作用

1、onCreateObservable方法:

该方法需要我们创建一个Observable对象,这个对象会在我们第三步创建的Repostory里返回,方法体提供了一个RetrofitConverter对象,用来创建Observable,而这个RetrofitConverter是我们第二步创建出来,第三部绑定的。

2、targetBeanType方法

这个方法很关键,上面说到Repository的targetClazz方法会返回一个class,就是由这个方法指定的,除此之外它还有个更关键的功能,我下面再说。

其他两个onSuccessCodePair和onErrorMessageKey方法现在用不到,后面再讲。

5、使用示例

前面准备了怎么多,我们开始使用。

/** * 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;        }    }}复制代码

6、使用@Presenter注解初始化Presenter

1、任意一个类型为LifecyclePresenter 的成员变量加上@Presenter注解,在Activity的onCreate时就会被创建好。

@Presenterprivate LifecyclePresenter presenter;复制代码

PS:之所以叫做LifecyclePresenter,是因为它具有生命周期感知功能,无需使用者关心生命周期的问题,比如释放Presenter,同时它内部集成了BKnife,默认会管理BKnife的初始化与解除绑定等与生命周期相关的操作(使用者在自己的工程添加BKnife的依赖即可)。

2、在onCreate中绑定数据仓库

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_simple_demo);    //绑定数据仓库    presenter.setRepository(new MarketRepository());}复制代码

通过new的方式初始化MarketRepository是不优雅的,不建议这样做,真正的做法是使用RepositoryInjection:下一节见。

转载地址:http://fcxna.baihongyu.com/

你可能感兴趣的文章
使用HCL模拟器配置DHCP相关项目
查看>>
OC中的NSSet(集合)
查看>>
为什么C++所有程序员都值得一学?
查看>>
如何隐藏IP地址
查看>>
网络yum源
查看>>
WSUS规划部署(一)安装部署WSUS
查看>>
谷歌浏览器不能通过页面打开摄像头的处理
查看>>
mysql+heartbeat双主高可用
查看>>
输入框字数统计(通过键盘输入和拷贝粘贴皆可)
查看>>
Qt笔记(1)连接 SQL Server 数据库
查看>>
记一次使用官方zabbix官方模板监控redis自己犯的错
查看>>
ASP.NET CS文件中输出JavaScript脚本的3种方法以及区别
查看>>
mysql 分隔某个字段
查看>>
《从零开始学Swift》学习笔记(Day 17)——Swift中数组集合
查看>>
traceroute路由追踪
查看>>
Bacula笔记
查看>>
我的友情链接
查看>>
svn merge以及Unknown action received: skipped conflicted path冲突解决
查看>>
CSS: the different of using CSS between @import and link
查看>>
f2fs 系列之七:page cache相关操作和接口
查看>>