引言
前面介绍过lambda和RxJava的使用后,那么下面我们将进入Retrofit + RxJava2.0 + Lambda三个框架的联合使用.
当然中间涉及注解相关的可以参考以下:
Annotation注解APT(一):什么是Annotation注解
Annotation注解APT(二):自定义注解
Annotation注解APT(三):依赖注入是什么
Annotation注解APT(四):依赖注入框架Dagger
Annotation注解APT(五):注入框架ButterKnife
一.Retrofit
"A type-safe HTTP client for Android and Java"这是官网的描述,也就是说Retrofit是一个类型安全的http客户端,那么如何理解和使用,我们来通过一个简单的demo开始:
为方便网络请求测试,将使用这个url:
可以在浏览器中拉下数据看下:
{
"ret": 1,
"msg": "成功",
"data": [
{
"id": 0,
"name": "qianyan.mp4",
"url": "https://bj.bcebos.com/course-mct/media/qianyan.mp4?authorization=bce-auth-v1%2Fde89d2e06dd7443a9e4422d5b3fb4eea%2F2017-06-24T09%3A02%3A16Z%2F6000%2F%2Fc26012cc47193c73f00bffda032373c1d189d2b3f64253bcc926860ee33b4901",
"title": "前言"
},
//这里省略
.....
{
"id": 18,
"name": "50yinjieshu.mp4",
"url": "https://bj.bcebos.com/course-mct/media/50yinjieshu.mp4?authorization=bce-auth-v1%2Fde89d2e06dd7443a9e4422d5b3fb4eea%2F2017-06-24T09%3A02%3A21Z%2F6000%2F%2F33a50f2217e60537044a49b8a69ea72f3bfc684288a67c1d2e63e2b808debe95",
"title": "结束"
}
]
}
可以看出,这是一个标准json格式,因此我们在添加库的时候,还应该添加json的解析工厂库.
开始,先配置app build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
testCompile 'junit:junit:4.12'
compile 'com.squareup.retrofit2:retrofit:2.2.0' //Retrofit
compile 'com.squareup.retrofit2:converter-gson:2.2.0' //GsonConverterFactory
}
根据json数据格式,我们新建要保存数据的bean:
public class RetrofitEntity {
private int ret; //对应json中的ret字段
private String msg; //对应json中的msg字段
private List<Subject> data; //对应json中的data字段
public int getRet() {
return ret;
}
public void setRet(int ret) {
this.ret = ret;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public List<Subject> getData() {
return data;
}
public void setData(List<Subject> data) {
this.data = data;
}
}
public class Subject {
private int id; //对应json中的id字段
private String name; //对应json中的name字段
private String title; //对应json中的title字段
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
请求接口类:
public interface MyApiEndpointInterface {
@POST("AppFiftyToneGraph/videoLink")
Call<RetrofitEntity> getAllVedio(@Body boolean once_no);
}
测试1,异步方法(enqueue)
static String BASE_URL = "http://www.izaodao.com/Api/";
//retrofit异步请求
public void test_1(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);
Call<RetrofitEntity> call = apiService.getAllVedio(true);
mycall = call;
call.enqueue(new Callback<RetrofitEntity>() {
@Override
public void onResponse(Call<RetrofitEntity> call, Response<RetrofitEntity> response) {
RetrofitEntity entity = response.body();
if(entity.getRet() == 1){
Log.i("tag", "onResponse----->" + entity.getMsg());
List<Subject> data = entity.getData();
for(Subject subject : data){
Log.i("tag", "----------------------------------------------" + subject.getId());
Log.i("tag", "name :" + subject.getName());
Log.i("tag", "title:" + subject.getTitle());
}
}
}
@Override
public void onFailure(Call<RetrofitEntity> call, Throwable t) {
Log.i("tag", "onFailure----->" + t.toString());
}
});
}
测试2,同步方法()
static String BASE_URL = "http://www.izaodao.com/Api/";
//同步请求,不能在ui线程调用此方法
public void test_2(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);
Call<RetrofitEntity> call = apiService.getAllVedio(true);
mycall = call;
try {
Response<RetrofitEntity> response = call.execute();
if(response != null){
RetrofitEntity entity = response.body();
if(entity.getRet() == 1){
Log.i("tag", "onResponse----->" + entity.getMsg());
List<Subject> data = entity.getData();
for(Subject subject : data){
Log.i("tag", "----------------------------------------------" + subject.getId());
Log.i("tag", "name :" + subject.getName());
Log.i("tag", "title:" + subject.getTitle());
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
二.Retrofit + RxJava2.0
RxJava可以参考这篇文章:RxJava2:observeOn和subscribeOn的使用
先添加对RxJava的依赖:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
testCompile 'junit:junit:4.12'
//rxjava
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.squareup.retrofit2:retrofit:2.2.0' //Retrofit
compile 'com.squareup.retrofit2:converter-gson:2.2.0' //GsonConverterFactory
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
}
MyApiEndpointInterface中添加支持接口:
public interface MyApiEndpointInterface {
@POST("AppFiftyToneGraph/videoLink")
Call<RetrofitEntity> getAllVedio(@Body boolean once_no);
@POST("AppFiftyToneGraph/videoLink")
Observable<RetrofitEntity> getAllVedioBy(@Body boolean once_no);
}
测试3
static String BASE_URL = "http://www.izaodao.com/Api/";
//RxJava + Retrofit
public void test_3(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);
Observable<RetrofitEntity> observable = apiService.getAllVedioBy(true);
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<RetrofitEntity>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(RetrofitEntity entity) {
if(entity.getRet() == 1){
Log.i("tag", "onResponse----->" + entity.getMsg());
List<Subject> data = entity.getData();
for(Subject subject : data){
Log.i("tag", "----------------------------------------------" + subject.getId());
Log.i("tag", "name :" + subject.getName());
Log.i("tag", "title:" + subject.getTitle());
}
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.i("tag", "onComplete");
}
});
}
三.Retrofit + RxJava2.0 + Lambda
lambda的思想,个人理解是对于确定的类型,可以像匿名内部内一样使用.
还是一样,先配置:lambda:在android studio中的配置和使用lambda表达式
对于测试3,如果我们这样使用:
测试4:
static String BASE_URL = "http://www.izaodao.com/Api/";
public void test_4(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);
Observable<RetrofitEntity> observable = apiService.getAllVedioBy(true);
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<RetrofitEntity>() {
@Override
public void accept(RetrofitEntity entity) throws Exception {
if(entity.getRet() == 1){
Log.i("tag", "onResponse----->" + entity.getMsg());
List<Subject> data = entity.getData();
for(Subject subject : data){
Log.i("tag", "----------------------------------------------" + subject.getId());
Log.i("tag", "name :" + subject.getName());
Log.i("tag", "title:" + subject.getTitle());
}
}
}
});
}
因此再变成测试5:
static String BASE_URL = "http://www.izaodao.com/Api/";
public void test_4(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyApiEndpointInterface apiService = retrofit.create(MyApiEndpointInterface.class);
Observable<RetrofitEntity> observable = apiService.getAllVedioBy(true);
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(entity -> {
if(entity.getRet() == 1){
Log.i("tag", "onResponse----->" + entity.getMsg());
List<Subject> data = entity.getData();
for(Subject subject : data){
Log.i("tag", "----------------------------------------------" + subject.getId());
Log.i("tag", "name :" + subject.getName());
Log.i("tag", "title:" + subject.getTitle());
}
}
},onError->{
Log.i("tag", "onError:" + onError.getMessage());
});
}
这样是不是很好理解了.
如果想继续深入了解Retrofit + Rxjava,可以看这个专栏:
http://blog.youkuaiyun.com/column/details/13297.html
一.@SerializedName注解
上面的实例中RetrofitEntity和Subject中的元素和json中的各个字段是一一对应的,如果json中字段的名称发生了变化,那么我们的代码及调用接口都要变化,这样使用起来很不方便,如果我们使用@SerializedName注解就很方便了,只需要改字段名称即可:
public class RetrofitEntity {
@SerializedName("ret")
private int ret_num; //对应json中的ret字段
@SerializedName("msg")
private String message; //对应json中的msg字段
@SerializedName("data")
private List<Subject> data; //对应json中的data字段
public int getRet() {
return ret_num;
}
public void setRet(int ret) {
this.ret_num = ret;
}
public String getMsg() {
return message;
}
public void setMsg(String msg) {
this.message = msg;
}
public List<Subject> getData() {
return data;
}
public void setData(List<Subject> data) {
this.data = data;
}
}
是不是很方便?