XRetrofit ,一个带你学习Retrofit简单代码。

介绍

XRetrofit 是一个极致模仿Retrofit 的风格代码,代码没有Retrofit 复杂,简单易懂。

支持getpostputdelete 请求,这些使用都一样。
简化文件上传,跟下载 使用@DOWNLOAD@UPLOAD
简化post 表单请求跟JOSN请求。
支持转换器,如果需要Gson的转换器,可以去demo那边去复制
支持适配器,内置跟Retrofit的Call<String>,当然了String可以替换任意的类型,跟Retrofit一样
没有内置Rxjava的适配器,如果需要,自己去demo那边复制。

区别

Retrofit 属于运行时注解,通过动态代理生成一个代码
XRetrofit 属于编译时注解,通过APT生成代码,如果要学习APT,可以操作这篇文章《带你了解APT》点击传送门

依赖, 只支持androidX,没有supper版本
    implementation 'com.yanxuwen.xretrofit:xretrofit:2.0.0'
    annotationProcessor 'com.yanxuwen.xretrofit:xretrofit-compiler:2.0.0'

使用方法,跟Retrofit一样,要定义接口,唯一区别在于在类上面要添加注解@NetServiceClass

定义接口,该例子分别写了RxjavaCall同步请求的使用

@NetServiceClass
public interface NetService {
    /**
     * Rxjava  适配器
     */
    @GET("api/manage-home/v5/home/detail-v2")
    Observable<HomeInfoV5> get(@Query("page") int page, @Query("limit") int limit);

    /**
     * 自带Call  适配器
     */
    @GET("api/manage-home/v5/home/{version}")
    Call<HomeInfoV5> get(@Path("version") String version, @Query("page") int page, @Query("limit") int limit);

    /**
     * 同步请求
     */
    @GET("api/manage-home/v5/home/detail-v2")
    String get3(@Query("page") int page, @Query("limit") int limit);

}

执行请求,以Call 适配器为例子

   public void onGet2(View view) {
        Call<HomeInfoV5> call = HttpRequest.getNetService().get("detail-v2", 0, 10);
        call.enqueue(new MyCallBack<HomeInfoV5>(this) {

            @Override
            public void success(HomeInfoV5 s) {
                Log.e("yxw", "onGet:" + s.getMsg());
            }

            @Override
            public void fail(String msg) {
                Log.e("yxw", "onGet:" + msg);
            }

            @Override
            public void cancel() {
                Log.e("yxw", "cancel");
            }
        });

    }

执行请求,以Rxjava 适配器为例子


    /**
     * get请求
     */
    public void onGet(View view) {
        Observable<HomeInfoV5> observable = HttpRequest.getNetService().get(0, 10);
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        Log.e("yxw","取消订阅2");
                    }
                })
                .as(AutoDispose.<HomeInfoV5>autoDisposable(
                        AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_PAUSE)))//OnDestory时自动解绑
                .subscribe(new Observer<HomeInfoV5>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.e("yxw", "onGet2 onSubscribe ");
                    }

                    @Override
                    public void onNext(@NonNull HomeInfoV5 homeInfoV5) {
                        Log.e("yxw", "onGet2 onNext " + homeInfoV5.getMsg());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e("yxw", "onGet2 fail " + e.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.e("yxw", "onGet2 onComplete ");
                    }
                });

    }

    }

POST请求如何区分表单跟JOSN,,这里我们抛弃了Retrofit的复杂度

例子如下:表单请求

    @FORM
    @POST("https://bx-uat.bisinuolan.cn/api/login/mobile")
    Call<String> postForm(@Param("mobile") String mobile, @Param("sms_code") String sms_code);

注意2个注解 @FORM@Param 我们舍弃了Retrofit的 @Field@FormUrlEncoded
@FORM 替换了@FormUrlEncoded 来区分是否表单
@Param 替换了@Field
@Param 有个好处就是:
1、不管是表单请求还JSON请求,都是可以作为参数来传参
2、如果用来Json请求的话,他会作为json格式的最外层数据,
哎这个怎么解释呢。就是如果你用@Param("userId"),那么最终传参是

{
    "userId": "c053e1a2-7335-4451-9201-e25e805a19f5-1578390821008"
}

@Body 注解,可以这样传

    /**
     * json 整串提交
     */
    @POST("api/customer/v1/open/user/level/my")
    Call<String> postJson2(@Body String json);

    /**
     * json 实体类提交
     */
    @POST("api/customer/v1/open/user/level/my")
    Call<String> postJson(@Body LoginBuild json);

@Body 注解跟Retrofit 注解一样,拥有一个功能,那是转换器,在添加转换器的时候,我们会通过 @Body 注解,判断当前是什么类型,然后通过类型,进行转换你想要的数据。。
上面的那个实体类提交就是这个原理,判断是Object类型的话,然后将Object类型转换为JSON格式进行提交。
那么你就可以定义你们公司需要啥类型,做啥处理。反正你们自己想。


配置。这个是跟Retrofit是一样的。。

    OkHttpClient client = new OkHttpClient
            .Builder()
            .connectTimeout(15, TimeUnit.SECONDS)//连接超时时间
            .readTimeout(15, TimeUnit.SECONDS)//读取超时时间
            .writeTimeout(15, TimeUnit.SECONDS)//写入超时时间
            .retryOnConnectionFailure(false)//连接不上是否重连,false不重连
            .hostnameVerifier(new TrustAllHostnameVerifier())//校验名称,这个对象就是信任所有的主机,也就是信任所有https的请求
            .sslSocketFactory(SslUtils.getSslSocketFactory().sSLSocketFactory, SslUtils.getSslSocketFactory().trustManager)
            .build();
    HttpManager.Builder()
            .baseUrl("https://bxapi.bisinuolan.cn/")
            .addConverterFactory(GsonConverterFactories.create())//FastJson转换器、可以替换成Gson
            .addCallAdapterFactory(Rxjava2CallAdapterFactories.create())//Rxjava2适配器,不配置有自带Call适配器
            .client(client)
            .build();

出如何初始呢,NetService (类名是随便定义的)接口呢,那就是下面那个

public class HttpRequest {

    private static NetService netService;

    public static NetService getNetService() {
        try {
            if (netService == null) {
                synchronized (HttpRequest.class) {
                    if (netService == null) {
                        netService = (NetService) Class.forName(HttpManager.getImplName(NetService.class))
                                .getConstructor().newInstance();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return netService;
    }
}

然后使用的时候就是直接
HttpRequest.getNetService().get(0, 10);


github 点击跳转

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容