Android Retrofit2+Rxjava2 初学总结

Android Retrofit2+Rxjava2 初学总结

此文针对初学android开发,基础比较薄弱的同学。总结了自己在使用Retrofit2+Rxjava2框架发送请求的一些经验。
由于只是为了实现功能,所以在代码的封装以及优化上没有做什么改进。

首先,一个请求,对应的url地址我们把它分为三个部分。
以我自己申请的一个api接口为例,我申请了一个获取手机号归属地api,具体使用方法在https://www.jisuapi.com/api/shouji/可以查看,大家也可以使用这个网站的其他api

它的请求地址的示例是这样:
https://api.jisuapi.com/shouji/query?appkey=yourappkey&shouji=13456755448
我们可以发现大部分请求都是这种格式,下面来说一下各个部分的含义
第一部分: https://api.jisuapi.com/shouji/ 这部分是基础url
第二部分:query (即?之前的那部分)这是请求名称
第三部分:appkey=yourappkey&shouji=13456755448 这是请求参数以及其对应的值
appkey和shouji分别是两个请求参数,它们等号后面是对应的值,每个请求参数之间是以&间隔的
当然,第二部分的请求名称不一定是query,也可以是shouji/query ,这时候只需要把基础url写为 https://api.jisuapi.com/即可

知道了请求地址的含义之后,我们还需要知道该请求返回的数据格式
一般来说,请求返回的是json对象,基础的做法是把json里的数据通过JSONObject取出并给对应的bean赋值
但这个方法往往过于繁琐,因此我们需要用到retrofit框架中的converter-gson

下面结合我的demo说说具体的使用步骤
第一步:添加依赖包

    //RxAndroid
    implementation 'io.reactivex:rxandroid:1.1.0'
    //retrofit依赖Gson
    implementation 'com.squareup.retrofit2:converter-gson:2.0.0'
    //retrofit依赖RxJava
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.0.0'

我总共用到了这三个包,先大概解释下每个包在我代码中的作用,后面会具体说明
rxandroid 用到了AndroidSchedulers类的.mainThread()方法,指定操作要在主线程进行
converter-gson 用于将返回的json对象自动转化为bean类
adapter-rxjava 使用rxjava的观察者模式回调数据

第二步:创建返回结果的javabean
新建一个LocationRes类,里面的内容用GsonFormat插件自动生成,这样对应返回的json格式不会出错
在https://www.jisuapi.com/api/shouji/中我们可以查看返回的json字符串示例,复制它

{
    "status": 0,
    "msg": "ok",
    "result": {
        "province": "浙江",
        "city": "杭州",
        "company": "中国移动",
        "cardtype": "GSM"
    }
}

在file-settings-plugin中下载安装GsonFormat插件,在创建的类中alt+insert选择GsonFormat,在粘贴板中粘贴以上内容
则会自动生成javabean,效果如下

package com.putt.phonedemo;

public class LocationRes {

    /**
     * status : 0
     * msg : ok
     * result : {"province":"浙江","city":"杭州","company":"中国移动","cardtype":"GSM"}
     */

    private int status;
    private String msg;
    private ResultBean result;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public ResultBean getResult() {
        return result;
    }

    public void setResult(ResultBean result) {
        this.result = result;
    }

    public static class ResultBean {
        @Override
        public String toString() {
            return "province='" + province + '\'' +
                    ", city='" + city + '\'' +
                    ", company='" + company + '\'' +
                    ", cardtype='" + cardtype + '\'';
        }

        /**
         * province : 浙江
         * city : 杭州
         * company : 中国移动
         * cardtype : GSM
         */

        private String province;
        private String city;
        private String company;
        private String cardtype;

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getCompany() {
            return company;
        }

        public void setCompany(String company) {
            this.company = company;
        }

        public String getCardtype() {
            return cardtype;
        }

        public void setCardtype(String cardtype) {
            this.cardtype = cardtype;
        }
    }
}

第三步:创建请求接口
新建一个PhoneService的接口

public interface PhoneService {
    @GET("shouji/query")
    Observable<LocationRes> getLocation(@Query("appkey") String key, @Query("shouji") String shouji);
}

每个@get注解修饰一个请求的方法,可以有多个请求,括号内是请求名称
这里我的请求参数是shouji/query,注意不要多余地在前方加上/或者后方加上?,因为基础url必须以/结尾

这里我定义了一个getLocation方法
它的返回对象是Observable< LocationRes> ,Observable是rxjava中的被观察者,泛型传入LocationRes对象
方法的参数以@query注解修饰,有几个请求参数就有几个@query

第四步:创建一个retrofit工具类
新建RetrofitHelper类

public class RetrofitHelper {
    private static final String REQUEST_PATH = "https://api.jisuapi.com/";

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(2, TimeUnit.MINUTES)
            .writeTimeout(2, TimeUnit.MINUTES)
            .readTimeout(2, TimeUnit.MINUTES)
            .build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(REQUEST_PATH)//基地址
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    PhoneService phoneService = retrofit.create(PhoneService.class);

    public Observable<LocationRes> getData(String key, String shouji) {
        return phoneService.getLocation(key, shouji);
    }
}

实例化一个OkHttpClient,设置几个超时时间
实例化一个Retrofit,传入基础url和上面的OkHttpClient
addConverterFactory,添加解析工具,传入创建的converter-gson包的GsonConverterFactory
addCallAdapterFactory,添加RxJava适配器,传入创建的adapter-rxjava包的RxJavaCallAdapterFactory
实例化一个PhoneService并赋值
定义一个getData方法,返回PhoneService的getLocation方法

第五步:MainActivity中的调用

public class MainActivity extends AppCompatActivity {

    private static final String KEY = "a19f7a97539e8abc";
    Button button;
    TextView textView;
    EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
    }

    private void initData() {
        button = findViewById(R.id.bt_query);
        textView = findViewById(R.id.tv_consequence);
        editText = findViewById(R.id.et_phone);
    }

    public void query(View v) {
        //调用封装好的retrofit请求方法
        RetrofitHelper retrofitHelper = new RetrofitHelper();
        retrofitHelper.getData(KEY, editText.getText().toString())
                .subscribeOn(Schedulers.io())//IO线程
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<LocationRes>() {
                    //执行onNext后执行
                    @Override
                    public void onCompleted() {
                        Toast.makeText(MainActivity.this, "onCompleted!", Toast.LENGTH_SHORT).show();
                    }

                    //请求失败
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    //请求成功
                    @Override
                    public void onNext(LocationRes locationRes) {
                        textView.setText(locationRes.getResult().toString());
                    }
                });
    }
}

query方法为按钮的点击事件
先实例化一个RetrofitHelper,调用之前的getData方法获取Observable,参数分别为apikey和用户在文本框输入的手机号
observeOn:传入rxandroid包下的AndroidSchedulers.mainThread()方法,因为要进行ui操作,必须在主线程,否则会有警告
subscribe:用于设置观察者与被观察者的订阅关系,传入的observer为new Subscriber< LocationRes>,它需要做出回应,因此重写
onCompleted onError onNext 这三个方法
失败时进入onError,e.printStackTrace()查看错误信息
成功时进入onNext,这里写逻辑事件,紧接着进入onCompleted,这里一般写提示信息

效果如下
Android Retrofit2+Rxjava2 初学总结_第1张图片demo地址

https://github.com/Puttanata/Android

你可能感兴趣的:(android)