Android -- retrofit2 + rxjava 简单封装

本文详细介绍了如何使用Retrofit结合RxJava进行网络请求,包括依赖添加、初始化配置、接口定义、请求方法实现及异常处理策略。同时,针对不同响应格式的自定义解析策略也进行了深入探讨。

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

第一步 添加依赖

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'

初始化

private static Retrofit retrofit;
    private static OkHttpClient client;

    static {
        client = new OkHttpClient();
        retrofit = new Retrofit.Builder().baseUrl("http://127.0.0.1:8080").client(client).
                        addConverterFactory(GsonConverterFactory.create()).
//                        addConverterFactory(StringConverterFactory.create()).//自定义ConverterFactory
                        addCallAdapterFactory(RxJava2CallAdapterFactory.create()).
                        build();

    }
public static <T> void executeMethod(Flowable<T> flowable, final OnCallBack<T> callback) {
    flowable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .unsubscribeOn(Schedulers.io())
            .subscribe(new Subscriber<T>() {
                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                    if (callback != null) {
                        callback.onError(e);
                    }
                }

                @Override
                public void onComplete() {
                    if (callback != null) {
                        callback.onComplete();
                    }
                }

                @Override
                public void onSubscribe(Subscription s) {
                    s.request(Long.MAX_VALUE);
                }

                @Override
                public void onNext(T o) {
                    if (callback != null) {
                        callback.onSucceed(o);
                    }
                }
            });
}

创建返回接口,请求接口

public interface TestViewI extends BaseViewI {
    void onTest(TestBean data);
}
public interface TestI extends BasePresenterI {
    void Test(String s);
    void Test_post(String s);
}

实现请求接口,主要方法

RemoteApiFactoryUtils.executeMethod(RemoteApiFactoryUtils.createRemoteApi(API.class).Test(s), new RemoteApiFactoryUtils.OnCallBack<TestBean>() {
        @Override
        public void onSucceed(TestBean data) {
            if (testViewI!=null) {
                testViewI.onTest(data);
                //testViewI.toast("....");
            }
        }

        @Override
        public void onComplete() {
            if (testViewI!=null)
                testViewI.dismissPro();
        }

        @Override
        public void onError(Throwable e) {
            if (testViewI!=null) {
                if (e instanceof ParseException){
                    //testViewI.onError(.......);
                }//else ...
                testViewI.showConntectError();
                testViewI.dismissPro();
            }
        }
    });
}

接口 api

public interface API {

    String http = "";

    @GET(http+"")
    Flowable<TestBean> Test(@Query("sss")String sss);

    @Headers("Content-Type: application/x-www-form-urlencoded;charset=utf-8")
    @FormUrlEncoded
    @POST(http)
    Flowable<TestBean> Test_post(@Field("sss")String sss);


}

在mainactivity中实例化

testViewI = new TestViewI() {
    @Override
    public void onTest(TestBean data) {
        if (data.getError().equals("0")){
            Toast.makeText(MainActivity.this,"处理接口返回数据",Toast.LENGTH_SHORT).show();
        }else {

        }
    }

    @Override
    public NetType checkNetWork() {
        return null;
    }

    @Override
    public void showPro() {
        //等待请求加载
    }

    @Override
    public void dismissPro() {
        //等待请求加载消失
    }

    @Override
    public void toast(String message) {
        Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showConntectError() {
        //显示错误信息
    }

    @Override
    public void onError(ErrorCode code, String message) {
        //发生错误时调用
    }
};
testmpI = new TestmpI(testViewI);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        testmpI.Test("123");
    }
});

有时候会发生一些狗血的事,请求的接口在不同的情况下返回的数据格式会变,例如:

正常返回

{
    "code":100,
    "data":{
        "id":1,
        "...":"..."
    }
}

但是当调用接口查询的时候没有数据,那返回data数据格式就变,从object变成string

{

    "code":101,
    "data":""

}

不知道后台是怎么想的,反正数据格式一变就会报错无法解析。

后台不改,只能自己弄了。

自定义一个解析工厂类继承Converter.Factory抽象类,主要方法

@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                        Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));

    if(type.equals(TestBean.class))
        return new ToStringResponseConverter(gson,adapter,type);

    return new GsonResponseBodyConverter<>(gson, adapter);
}

@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
                                                      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
}

在解析返回时,如果有变化比较大的,单独处理,其他的都是一样的可以通用同一个解析类,主要方法

@Override
    public T convert(ResponseBody value) throws IOException {

        JsonReader jsonReader = null;
        try {
            String s = value.string();
            JSONObject jsonObject = new JSONObject(s);
            //对异常数据进行处理
//            if (type.equals(TestBean.class)) {
//
//                return gson.fromJson(String.valueOf(jsonObject), type);
//            }
            InputStream inputStream = new ByteArrayInputStream(jsonObject.toString().getBytes());
            Reader reader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            jsonReader = gson.newJsonReader(reader);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        if (jsonReader == null)
            jsonReader = gson.newJsonReader(value.charStream());
        try {
            T result = adapter.read(jsonReader);
            if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                throw new JsonIOException("JSON document was not fully consumed.");
            }
            return result;
        } finally {
            value.close();
        }

    }

小小记录一下。

完整项目地址添加链接描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值