您的位置:首页 > 编程语言 > Java开发

Retrofit实践(MVP+RxJava)

2016-08-24 10:53 543 查看

Retorfit实践(MVP+RxJava)

之前两篇文章分别介绍了 MVP 以及 RxJava,今天我们通过学习Retrofit来进一步介绍他们。文章目录如下:

Retorfit实践MVPRxJava
Retorfit介绍

Retorfit实践
添加依赖

Model层
定义请求接口

创建 Retrofit对象

View层

Presenter层

Retorfit介绍

Retrofit(GitHub)与okhttp共同出自于Square公司,retrofit底层使用okhttp实现,相比okhttp使用更加简便。我们只需要通过简单的配置就能使用retrofit来进行网络请求了

Retorfit实践

我们还是对我们之前已经实现MVP模式的 PM2.5程序进行修改

添加依赖

compile ‘io.reactivex:rxandroid:1.1.0’

compile ‘io.reactivex:rxjava:1.1.0’

compile ‘com.squareup.retrofit2:retrofit:2.0.2’

compile ‘com.squareup.retrofit2:converter-gson:2.0.2’

compile ‘com.squareup.retrofit2:adapter-rxjava:2.0.2’

compile ‘com.squareup.okhttp3:logging-interceptor:3.1.2’

Model层

这里我们使用Retrofit代替之前的Volly,下面具体介绍下Retrofit的使用

1.定义请求接口

public interface PM25Service {
String BASE_SERVER_URL = "http://apis.baidu.com/";
String API_KEY = "你申请的api key";

@GET("apistore/aqiservice/aqi")
Observable<AqiInfo>GetPM25Value(@Header("apikey")String apiKey,
@Query("city")String mCityName);
}


包含了需要进行网络请求的 URL , API KEY 以及 需要查询的城市名

这里用到了两个关键字 @Header 以及 @Query

@Header 代表填入请求的header,很直观

@Query 包含了需要的健值对配对,在Volly中,我们是在请求的URL中添加 “city = mCityName”,而Retrofit只是封装了更为直观的Query关键字

顺带一天,常用的还有@Path,代表占位符,比如

@GET("My Name is {name}")
Observable<User> getUser(@Path("name") String name);


我们可以通过 getUser(mName)来填充这个{name}占位符。

2.创建 Retrofit对象

public class PM25Client {
public static Retrofit mRetrofit;

public static Retrofit retrofit() {
OkHttpClient okHttpClient = builder.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(PM25Service.BASE_SERVER_URL)
//增加返回值为Gson的支持(以实体类返回)
.addConverterFactory(GsonConverterFactory.create())
//增加返回值为Oservable<T>的支持
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
}
return mRetrofit;
}
}


1) 使用建造者模式,对mRetrofit属性进行定制

2)添加Oservable< T >, 返回支持,也就是完成对RxJava的支持,RxJavaCallAdapterFactory是对类型进行转换的适配,结合RxJava的特点,我们很容易就可以猜到,底层实现一定是用了 flatMap 或者Map 操作符,具体我们下一篇文章会讲到,也顺便复习下RxJava.

View层

MVP的好处就是V和M层进行解耦,所以我们View层改动非常小,只要修改下

由于之前用Volly 所有在Model进行线程控制,而现在用Retorfit,线程控制我们提取到Presenter来进行,所有我们需要对Presenter做修改下带入的P就可以了。

原来:

public class PM25Activity extends MVPBaseActivity<PM25Presenter> implements PM25View


修改后:

public class PM25Activity extends MVPBaseActivity<PM25RetrofitPresenter> implements PM25View


Presenter层

由于我们网络请求框架更改了,所以我们也把P层做了修改

public PM25RetrofitPresenter(PM25View view) { //1.构造函数
attachView(view);
model = new PM25RetrofitModel();
mPM25Service = PM25Client.retrofit().create(PM25Service.class); //2.生成动态代理类
}
@Override
public void performOnClick(String mCityName) { //3.对View层传来的点击时间进行处理

// 4.订阅并对订阅时间进行处理
addSubscription(mPM25Service.GetPM25Value(PM25Service.API_KEY,mCityName),new SubscriberCallback<>(new rCallBack<AqiInfo>() {

@Override
public void onResult(AqiInfo data) {
String mTime = data.retData.time.substring(11,19);
mvpView.getPM25Success(data.retData.toString() + "更新时间 : " + mTime);
}

@Override
public void onFail(String data) {
mvpView.getPM25Fail(data);
}
}));
}


P层代码相对复杂,但是也比较有趣:

1.构造函数,初始化model和view层,并生成PM25Service的动态代理类

2.生成PM25Service的动态代理类,动态代理类实现了一个或者一组接口,目的是,其中任何一个接口的实例的方法调用将会被指派到统一的另一个接口的方法中,主要是在代理中在原有实现方法中添加其他实现,我们来看下retrofit.create是做了怎样的操作。

实现代码:

//只贴了最重要的部分实现
public <T> T create(final Class<T> service) {
Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();

@Override public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});


InvocationHandler 中覆写的 invoke() 方法,通过loadServiceMethod方法获得loadServiceMethod中首先从缓存中找解析的方法,找到直接返回,否则解析方法,然后放入缓存中,这样是为了提高效率。然后生成一个OkHttpCall 对象,这里的意图就很明显了,就是当调用到改代理方法,就进行okHttp的网络请求,OkHttp也就是这个代理的本体。当我们使用mPM25Service.GetPM25Value 的时候其实是调用了代理的invoke方法,在这里Retrofit巧妙的利用注解把接口转换成了一个HTTP请求,代理和注解就是Retrofit的核心!

回到Presenter层的代码:

4.订阅和处理订阅事件,这部分是对RxAndroid的具体体现:

public void addSubscription(Observable observable, Subscriber subscriber) {
if (compositeSubscription == null) {
compositeSubscription = new CompositeSubscription();
}
compositeSubscription.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber));
}


通过addSubscription这个方法,把所有observable都集合起来,这样方便进行订阅的内存管理

同时我们也可以看到P层就是在这个方法中进行线程控制,网络操作在io线程处理,而订阅响应时间在住线程中进行。

因为我们使用了compositeSubscription,所以对订阅事件的取消也非常方便

public void onUnsubscribe() {
if (compositeSubscription != null && compositeSubscription.hasSubscriptions()) {
compositeSubscription.unsubscribe();
}
}


最后通过 SubscriberCallback 把数据返回,并在View中更新

终于完成了MVP+RxJava+Retrofit的基础分享,非常感谢大牛写了这么好的框架~ 文章代码可以到这里下载,谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: