新浦京81707con > 注册购买 > 从零开始实战解析Retrofit

原标题:从零开始实战解析Retrofit

浏览次数:179 时间:2020-03-01

普通从服务端取得的JSON数据格式大概如下:

常常从服务端得到的JSON数据格式差相当的少如下:

趋之若鹜更新中,接待我们指正交流

 { "code":1, "message":"查询成功", "detail":{"aa":"123","bb":"123","cc":"123"} }
  {
    "code":1,
    "message":"查询成功",
    "detail":{"aa":"123","bb":"123","cc":"123"}
  }

实战深入分析Retrofit

法定链接http://square.github.io/retrofit/
github地址https://github.com/square/retrofit

由此普通大家会定义叁个实体类来解析对应的json:​

设若现身错误的状态那正是:

1. 作用

合法描述:对网络央浼的封装.
Use annotations to describe the HTTP request:
a. URL parameter replacement and query parameter support()
b. Object conversion to request body (e.g., JSON, protocol buffers)
c. Multipart request body and file upload
使用注脚描述HTTP request
a. 可动态进展UENVISIONL参数,query替换
b. 猖獗对象转变来诉求体(json,protocol buffers...卡塔尔国
c. 易拓宽的request body与公事上传

public class Response { @SerializedName private int code; @SerializedName("message") private String message; @SerializedName private DetailBean detail; //省略getter和setter方法... public static class DetailBean { @SerializedName private String aa; @SerializedName private String bb; @SerializedName private String cc; //省略getter和setter方法... }}
  {
    "code":0,
    "message":"密码错误!",
    "detail":null
  }
2. 带着难题:我们得以本人写代码封装网络层,为何要用Retrofit

找答案:
大咖Jake Wharton在 NYC 2016 的那么些分享中的演说,蕴涵了富有 Retrofit 2.0 的新特征,周到介绍了 Retrofit 2.0 专门的学问原理
大家能够从Jake Wharton的解说中找到一些答案,同卓殊候也对Retrofit的全局设计有起头的认知.
总结:

  1. U科雷傲L参数注明可替换@path@url//todo
  2. 帮忙种种U本田CR-VLClient(okhttp,UrlConnectionClient等卡塔尔(قطر‎
  3. 支撑多种行列换交换左券(Gson,xmlState of Qatar,利用Converter(转变器State of Qatar,转变器自行接受适当的反连串化方法
  4. 支持RxJava
  5. 内置Okhttp
  6. 归来与OKhttp形似的Call对象扶植同/异步操作,可每一天撤销.注意同步只可以进行壹次,要频繁clone下
  7. 参数化的 Response 类型,方便获取央求头消息,已更动好的重临体等.
  8. 拓展性的CallAdapter
    去实战心得

沉思:大家项目利用okhttp,而且本人写代码对它实行了包装,寻思是还是不是要选取Retrofit.那就深深的问询下
设想到现行反革命更为流行响应式,流式编制程序观念来弥补面向对象思想编制程序观念的部分不足

个中的code字段表示处境,比如以下值恐怕代表了分化的含义

进而普通大家会定义二个实体类来解析对应的json:

3. Demo型实战:github demo
  1. New Project,导库
    compile 'com.squareup.retrofit2:retrofit:2.1.0',
    增进网络央浼权限.
  2. API初试
    看下官网demo和一部分博客,本人出手.
  • code = 1, 表示成功, 不等于1表示错误
  • code = -101, 表示token过期
  • code = -102, 表示手提式有线电话机号码已经登记
  • 等等等
data class BaseResponse<T>(
        var code: Int,
        var message: String,
        var detail: T
)
2.1 先创造多少个Github瑟维斯接口,定义二个办法用来央浼 https://api.github.com/users/xwpeng/repos

Bean:Repo2用GsonFromat插件快速生成//todo null的管理

    public interface GithubService {    
   // https://api.github.com/users/xwpeng/repos    
   @GET("users/{user}/repos")    
   Call<List<Repo2>> listRepos(@Path("user") String user);
   }

解析:
@GET表明用get请求;
users/{user}/repos代表央求url的后缀;
{user}能够用@Path动态传入;
回去二个Call,List<Repo2>指Call试行后归来的Response的body;
申明用法源码描述得很详细.

假设大家依照正规的Retrofit ENCORExJava逻辑来拍卖,写出来的代码如下所示:

里面包车型大巴code字段表示境况,比方以下值可能代表了分歧的意义

写作业类TestRetrofit
   private static GithubService getService(String baseUrl, Converter.Factory factory) {   
   Retrofit.Builder builder = new Retrofit.Builder().baseUrl(baseUrl);    
   if (factory != null) {        
   builder.addConverterFactory(factory);    
   }    
   Retrofit retrofit = builder.build();   
   return retrofit.create(GithubService.class);
   }

解析:
Retrofit的Builder格局布局一个Retrofit对象retrofit;
调用retrofit.create(GithubService.classState of Qatar,重回叁个GithubService对象;
GithubService对象调用你阐明的不二等秘书诀得到贰个Call,通过Call实行网络央求;
baseUrl必填,必须以"/"结尾,一个url的门道由baseUrl与endpoint组成,endpoint即类型@Get(xxx卡塔尔(قطر‎中的xxx,它们有写法则范供给,能够看下baseUrl(卡塔尔国的陈诉;
addConverterFactory(卡塔尔(قطر‎:增添叁个转变器工厂,详细的情况在下文写出;
addCall艾达pterFactory(卡塔尔:增添Call适配器,详细的情况见下文;
其他措施不常用,自个儿看源码;
public static void base() {
final Call<List<Repo2>> repoCall = getService("https://api.github.com/", GsonConverterFactory.create()).listRepos("xwpeng");
//同步伏乞
/*
new Thread(new Runnable() {
@Override
public void run() {
Response<List<Repo2>> response = null;
try {
response = repoCall.execute();
Log.d(TAG, response.body().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
*/

    //异步
    repoCall.enqueue(new Callback<List<Repo2>>() {
        @Override
        public void onResponse(Call<List<Repo2>> call, Response<List<Repo2>> response) {
            try {
                for (Repo2 repo2 : response.body()) {
                    Log.d(TAG, "enqueue: "   repo2.toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<List<Repo2>> call, Throwable t) {
            Log.e(TAG, t.getMessage());
        }
    });
   }

解析:
获得Call对象之后,调用execute(卡塔尔国同步央浼,直接回到response.body(State of Qatar就是List<Repo2>对象;
调用enqueue(Callback callback卡塔尔国传回调方法开展异步央求,onResponse(State of Qatar成功重回数据,onFailure(卡塔尔(قطر‎失利;

//ApiService.javapublic interface ApiService { String ENDPOINT = Constants.END_POINT; @POST("app/api") Observable<Response1> request1(@Body Request1 request); @POST("app/api") Observable<Response2> request2(@Body Request2 request); /** * Create a new ApiService */ class Factory { private Factory() { } public static ApiService createService { OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); builder.readTimeout(10, TimeUnit.SECONDS); builder.connectTimeout(9, TimeUnit.SECONDS); if (BuildConfig.DEBUG) { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); builder.addInterceptor(interceptor); } builder.addInterceptor(new HeaderInterceptor; OkHttpClient client = builder.build(); Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiService.ENDPOINT) .client .addConverterFactory(GsonConverterFactory.create .addCallAdapterFactory(RxJavaCallAdapterFactory.create .build(); return retrofit.create(ApiService.class); } }}
  • code = 1, 表示成功
  • code !=1 ,代表错误
  • 等等等
2.2 Converter转换器

Converter用于诉求参数与重临参数的调换.
乞求参数调换:@Post的@Body的修饰参数类型是用RequestBody,若是您想传实体可能json对象,就先得由Converter调换来RequestBody.能够看看GsonConverter源码.
若是服务端要的伸手数据的格式(要注意MediaType,比如text/x-json与appcation/json是有分其余卡塔尔(قطر‎未有现有的Converter
要么写Converter(参谋GsonConverter卡塔尔,只怕创制一个RequestBody.
回去参数调换:Call央浼后赶回三个Response,Response泛型默以为okhttp3的ResponseBody,即response.body(卡塔尔国,它.string(卡塔尔国后正是服务器给您的体系化数据,如Json格式的数据.
将连串话数据转成Bean叫做剖析,能够在onResponse(卡塔尔中本身写方法实行解析.
大雅一点就应用Converter定义好分析法则,在Retrofit的Builder增加.
里面,有现有的GsonConverter,导入
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
compile 'com.google.code.gson:gson:2.7'
builder.addConverterFactory(GsonConverterFactory.create(State of Qatar卡塔尔(قطر‎就能够应用了.
突发性你的Bean字段与服务器重临的名字不对应,也许想直接用JsonObject剖析,那就融洽自定义Converter转变下
自定义的Converter如下:

   public class ResultConverter implements Converter<ResponseBody, Result>{
   @Override
   public Result convert(ResponseBody value) throws IOException {
   String valueString = value.string();
   NetResult netResult = new Gson().fromJson(valueString, NetResult.class);
   Result result = new Result();
   result.resultCode = netResult.resultcode;
   result.reason = netResult.reason;
   result.errorCode = netResult.error_code;
   result.contents = netResult.result;
   return result;
   }
   static class NetResult {
    /**
   * resultcode : 101
   * reason : KEY ERROR!
   * result : []
   * error_code : 10001
   */
   public String resultcode;
   public String reason;
   public int error_code;
   public List<String> result;
   }
   }

   public class ResultConverterFactory extends Converter.Factory {    
   @Override    
   public  Converter<ResponseBody, Result> responseBodyConverter(Type type, 
   Annotation[] annotations, Retrofit retrofit) {
    return new ResultConverter();   
   }}

######2.3 CallAdapter

(没陆风X8xjava根底先略过State of Qatar暗中同意再次回到是Call对象,要是要结合宝马X5xJava的话,必要回到三个Observable对象
CallAdapter就用来将Call对象转变来Observable对象,导入库开展利用
compile 'io.reactivex:rxjava:1.1.8'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

行使的时候:

接收自定义CustomizeGsonConverterFactory

2.4 RetrofitAPI扫描
ApiService mApiService = ApiService.Factory.createService();mApiService.request1 .subscribeOn(Schedulers.io .observeOn(AndroidSchedulers.mainThread .subscribe(new Subscriber<Response1>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Response1 response) { int code = response.getCode(); switch  { case 1: //do something break; case -101://do something break; case -102: //do something break; default: break; } } });
private fun createRetrofit(builder: Retrofit.Builder, client: OkHttpClient, url: String): Retrofit {
        return builder
                .baseUrl(url)
                .client(client)
//                .addConverterFactory(GsonConverterFactory.create())
                .addConverterFactory(CustomizeGsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
    }
@Query ?前面包车型地铁二个参数,如诉求链接https://github.com/xwpeng?tab=repositories
    @GET("{user}")
    Call<ResponseBody> testAnnotationQuery(@Path("user") String user, @Query("tab") String tab);

假使对每二个号令都这么做,那不是写死个人呢, 万一曾几何时这一个值变了, 例如从-102 形成了 -105 , 那你不是每一个地方全体都得改, 用脑筋想就骇人听大人讲!

addConverterFactory(GsonConverterFactory.create(State of Qatar卡塔尔国那句代码是为着用Gson把服务端重临的json数据剖析成实体的, 那就从这里入手,能够和煦定义一个GsonConverter,扩充一下原本的功用
暗许的GsonConverter由几个类组成:

@QueryMap Query的Map情势,如恳求链接https://www.google.com.hk/search?q=Retrofit&oq=Retrofit
   @GET("/")Call<ResponseBody>
   tsetAnnotationQueryMap(@QueryMap Map<String, String> queryMaps);

图片 1img.jpg

  • GsonConverterFactory // GsonConverter 工厂类, 用来创设GsonConverter
  • GsonResponseBodyConverter // 处理ResponseBody
  • GsonRequestBodyConverter // 处理RequestBody
@Url需要固定url
   @GET
   Call<Result> testAnnotationURl(@Url String url);

本文由新浦京81707con发布于注册购买,转载请注明出处:从零开始实战解析Retrofit

关键词: 新浦京81707con Android Android开发 自定义 错误

上一篇:Retrofit实现全局过期token自动刷新,Retrofit实现全

下一篇:没有了