android框架:Retrofit + RxJava2.0 + Lambda

本文介绍Retrofit结合RxJava与Lambda的使用方法,包括配置、接口定义及不同方式的数据请求处理,并展示了如何利用@SerializedName注解提高代码灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

前面介绍过lambdaRxJava的使用后,那么下面我们将进入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:

http://www.izaodao.com/API/AppFiftyToneGraph/videoLink

可以在浏览器中拉下数据看下:

{
  "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;
    }
}

是不是很方便? 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fishmov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值