• 这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)(转)


    前言

    • Andrroid开发中,网络请求十分常用
    • 而在Android网络请求库中,Retrofit是当下最热的一个网络请求库

    Github截图

    • 今天,我将献上一份非常详细Retrofit v2.0的使用教程,希望你们会喜欢。

    如果对Retrofit v2.0的源码感兴趣,可看文章:Android:手把手带你深入剖析 Retrofit 2.0 源码


    目录

    目录


    1. 简介

    Retrofit简介

    特别注意:

    • 准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
    • 原因:网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装

    本质过程

    • App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作
    • 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析

    2. 与其他开源请求库对比

    除了Retrofit,如今Android中主流的网络请求框架有:

    • Android-Async-Http
    • Volley
    • OkHttp

    下面是简单介绍:

    网络请求加载 - 介绍

    一图让你了解全部的网络请求库和他们之间的区别!

    网络请求库 - 对比


    附:各个主流网络请求库的Github地址


    3. 使用介绍

    使用 Retrofit 的步骤共有7个:

    步骤1:添加Retrofit库的依赖 
    步骤2:创建 接收服务器返回数据 的类 
    步骤3:创建 用于描述网络请求 的接口 
    步骤4:创建 Retrofit 实例 
    步骤5:创建 网络请求接口实例 并 配置网络请求参数 
    步骤6:发送网络请求(异步 / 同步)

    封装了 数据转换、线程切换的操作

    步骤7: 处理服务器返回的数据

    接下来,我们一步步进行讲解。

    步骤1:添加Retrofit库的依赖

    1. 在 Gradle加入Retrofit库的依赖

    由于Retrofit是基于OkHttp,所以还需要添加OkHttp库依赖

    build.gradle

    1 dependencies {
    2     compile 'com.squareup.retrofit2:retrofit:2.0.2'
    3     // Retrofit库
    4     compile 'com.squareup.okhttp3:okhttp:3.1.2'
    5     // Okhttp库
    6   }

    2. 添加 网络权限 
    AndroidManifest.xml

    <uses-permission android:name="android.permission.INTERNET"/>

    步骤2:创建 接收服务器返回数据 的类

    Reception.java

    1 public class Reception {
    2     ...
    3     // 根据返回数据的格式和数据解析方式(Json、XML等)定义
    4     // 下面会在实例进行说明
    5         }

    步骤3:创建 用于描述网络请求 的接口

    • Retrofit将 Http请求 抽象成 Java接口:采用 注解 描述网络请求参数 和配置网络请求参数 
      1. 用 动态代理 动态 将该接口的注解“翻译”成一个 Http 请求,最后再执行 Http 请求 
      2. 注:接口中的每个方法的参数都需要使用注解标注,否则会报错


    GetRequest_Interface.interface

     1 public interface GetRequest_Interface {
     2 
     3     @GET("openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q=car")
     4     Call<Translation>  getCall();
     5     // @GET注解的作用:采用Get方法发送网络请求
     6 
     7     // getCall() = 接收网络请求数据的方法
     8     // 其中返回类型为Call<*>,*是接收数据的类(即上面定义的Translation类)
     9     // 如果想直接获得Responsebody中的内容,可以定义网络请求返回值为Call<ResponseBody>
    10 }

    下面详细介绍Retrofit 网络请求接口 的注解类型。

    注解类型

    注解类型

    注解说明

    第一类:网络请求方法

    网络请求方法注解

    详细说明: 
    a. @GET、@POST、@PUT、@DELETE、@HEAD 
    以上方法分别对应 HTTP中的网络请求方式

    1 public interface GetRequest_Interface {
    2 
    3     @GET("openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q=car")
    4     Call<Translation>  getCall();
    5     // @GET注解的作用:采用Get方法发送网络请求
    6     // getCall() = 接收网络请求数据的方法
    7     // 其中返回类型为Call<*>,*是接收数据的类(即上面定义的Translation类)
    8 }

    此处特意说明URL的组成:Retrofit把 网络请求的URL 分成了两部分设置:

     1 // 第1部分:在网络请求接口的注解设置
     2  @GET("openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q=car")
     3 Call<Translation>  getCall();
     4 
     5 // 第2部分:在创建Retrofit实例时通过.baseUrl()设置
     6 Retrofit retrofit = new Retrofit.Builder()
     7                 .baseUrl("http://fanyi.youdao.com/") //设置网络请求的Url地址
     8                 .addConverterFactory(GsonConverterFactory.create()) //设置数据解析器
     9                 .build();
    10 
    11 // 从上面看出:一个请求的URL可以通过 替换块 和 请求方法的参数 来进行动态的URL更新。
    12 // 替换块是由 被{}包裹起来的字符串构成
    13 // 即:Retrofit支持动态改变网络请求根目录
    • 网络请求的完整 Url =在创建Retrofit实例时通过.baseUrl()设置 +网络请求接口的注解设置(下面称 “path“ )
    • 具体整合的规则如下:

    URL整合规则

    建议采用第三种方式来配置,并尽量使用同一种路径形式。

    b. @HTTP

    • 作用:替换@GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展
    • 具体使用:通过属性method、path、hasBody进行设置
     1 public interface GetRequest_Interface {
     2     /**
     3      * method:网络请求的方法(区分大小写)
     4      * path:网络请求地址路径
     5      * hasBody:是否有请求体
     6      */
     7     @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
     8     Call<ResponseBody> getCall(@Path("id") int id);
     9     // {id} 表示是一个变量
    10     // method 的值 retrofit 不会做处理,所以要自行保证准确
    11 }

    第二类:标记

    标记类注解

    a. @FormUrlEncoded

    • 作用:表示发送form-encoded的数据

    每个键值对需要用@Filed来注解键名,随后的对象需要提供值。

    b. @Multipart

    • 作用:表示发送form-encoded的数据(适用于 有文件 上传的场景) 

    每个键值对需要用@Part来注解键名,随后的对象需要提供值。 
    具体使用如下: 
    GetRequest_Interface

     1 public interface GetRequest_Interface {
     2         /**
     3          *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
     4          * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
     5          */
     6         @POST("/form")
     7         @FormUrlEncoded
     8         Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);
     9 
    10         /**
    11          * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
    12          * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
    13          */
    14         @POST("/form")
    15         @Multipart
    16         Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
    17 
    18 }
    19 
    20 // 具体使用
    21        GetRequest_Interface service = retrofit.create(GetRequest_Interface.class);
    22         // @FormUrlEncoded 
    23         Call<ResponseBody> call1 = service.testFormUrlEncoded1("Carson", 24);
    24 
    25         //  @Multipart
    26         RequestBody name = RequestBody.create(textType, "Carson");
    27         RequestBody age = RequestBody.create(textType, "24");
    28 
    29         MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
    30         Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);

    第三类:网络请求参数

    网络请求参数注解

    详细说明

    a. @Header & @Headers

    • 作用:添加请求头 &添加不固定的请求头
    • 具体使用如下:
     1 // @Header
     2 @GET("user")
     3 Call<User> getUser(@Header("Authorization") String authorization)
     4 
     5 // @Headers
     6 @Headers("Authorization: authorization")
     7 @GET("user")
     8 Call<User> getUser()
     9 
    10 // 以上的效果是一致的。
    11 // 区别在于使用场景和使用方式
    12 // 1. 使用场景:@Header用于添加不固定的请求头,@Headers用于添加固定的请求头
    13 // 2. 使用方式:@Header作用于方法的参数;@Headers作用于方法

    b. @Body

    • 作用:以 Post方式 传递 自定义数据类型 给服务器
    • 特别注意:如果提交的是一个Map,那么作用相当于 @Field 

    不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单,如:

    1 FormBody.Builder builder = new FormBody.Builder();
    2 builder.add("key","value");

    c. @Field & @FieldMap

    • 作用:发送 Post请求 时提交请求的表单字段
    • 具体使用:与 @FormUrlEncoded 注解配合使用
     1 public interface GetRequest_Interface {
     2         /**
     3          *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
     4          * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
     5          */
     6         @POST("/form")
     7         @FormUrlEncoded
     8         Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);
     9 
    10 /**
    11          * Map的key作为表单的键
    12          */
    13         @POST("/form")
    14         @FormUrlEncoded
    15         Call<ResponseBody> testFormUrlEncoded2(@FieldMap Map<String, Object> map);
    16 
    17 }
    18 
    19 // 具体使用
    20          // @Field
    21         Call<ResponseBody> call1 = service.testFormUrlEncoded1("Carson", 24);
    22 
    23         // @FieldMap
    24         // 实现的效果与上面相同,但要传入Map
    25         Map<String, Object> map = new HashMap<>();
    26         map.put("username", "Carson");
    27         map.put("age", 24);
    28         Call<ResponseBody> call2 = service.testFormUrlEncoded2(map);

    d. @Part & @PartMap

    • 作用:发送 Post请求 时提交请求的表单字段

      与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 有文件上传 的场景

    • 具体使用:与 @Multipart 注解配合使用

     1 public interface GetRequest_Interface {
     2 
     3           /**
     4          * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
     5          * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
     6          */
     7         @POST("/form")
     8         @Multipart
     9         Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
    10 
    11         /**
    12          * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型,
    13          * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的 {@link retrofit2.converter.gson.GsonRequestBodyConverter}
    14          * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用<b> @Part MultipartBody.Part </b>
    15          */
    16         @POST("/form")
    17         @Multipart
    18         Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);
    19 
    20         @POST("/form")
    21         @Multipart
    22         Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> args);
    23 }
    24 
    25 // 具体使用
    26  MediaType textType = MediaType.parse("text/plain");
    27         RequestBody name = RequestBody.create(textType, "Carson");
    28         RequestBody age = RequestBody.create(textType, "24");
    29         RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");
    30 
    31         // @Part
    32         MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
    33         Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);
    34         ResponseBodyPrinter.printResponseBody(call3);
    35 
    36         // @PartMap
    37         // 实现和上面同样的效果
    38         Map<String, RequestBody> fileUpload2Args = new HashMap<>();
    39         fileUpload2Args.put("name", name);
    40         fileUpload2Args.put("age", age);
    41         //这里并不会被当成文件,因为没有文件名(包含在Content-Disposition请求头中),但上面的 filePart 有
    42         //fileUpload2Args.put("file", file);
    43         Call<ResponseBody> call4 = service.testFileUpload2(fileUpload2Args, filePart); //单独处理文件
    44         ResponseBodyPrinter.printResponseBody(call4);
    45 }

    e. @Query和@QueryMap

    • 作用:用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)

      如:url = http://www.println.net/?cate=android,其中,Query = cate

    • 具体使用:配置时只需要在接口方法中增加一个参数即可:

    1    @GET("/")    
    2    Call<String> cate(@Query("cate") String cate);
    3 }
    4 
    5 // 其使用方式同 @Field与@FieldMap,这里不作过多描述

    f. @Path

    • 作用:URL地址的缺省值
    • 具体使用:
    1 public interface GetRequest_Interface {
    2 
    3         @GET("users/{user}/repos")
    4         Call<ResponseBody>  getBlog(@Path("user") String user );
    5         // 访问的API是:https://api.github.com/users/{user}/repos
    6         // 在发起请求时, {user} 会被替换为方法的第一个参数 user(被@Path注解作用)
    7     }

    g. @Url

    • 作用:直接传入一个请求的 URL变量 用于URL设置
    • 具体使用:
    1 public interface GetRequest_Interface {
    2 
    3         @GET
    4         Call<ResponseBody> testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);
    5        // 当有URL注解时,@GET传入的URL就可以省略
    6        // 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供
    7 
    8 }

    汇总

    汇总

    步骤4:创建 Retrofit 实例

    1  Retrofit retrofit = new Retrofit.Builder()
    2                 .baseUrl("http://fanyi.youdao.com/") // 设置网络请求的Url地址
    3                 .addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
    4                 .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava平台
    5                 .build();

    a. 关于数据解析器(Converter)

    • Retrofit支持多种数据解析方式
    • 使用时需要在Gradle添加依赖
    数据解析器Gradle依赖
    Gson com.squareup.retrofit2:converter-gson:2.0.2
    Jackson com.squareup.retrofit2:converter-jackson:2.0.2
    Simple XML com.squareup.retrofit2:converter-simplexml:2.0.2
    Protobuf com.squareup.retrofit2:converter-protobuf:2.0.2
    Moshi com.squareup.retrofit2:converter-moshi:2.0.2
    Wire com.squareup.retrofit2:converter-wire:2.0.2
    Scalars com.squareup.retrofit2:converter-scalars:2.0.2

    b. 关于网络请求适配器(CallAdapter)

    • Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava 

      使用时如使用的是 Android 默认的 CallAdapter,则不需要添加网络请求适配器的依赖,否则则需要按照需求进行添加 
      Retrofit 提供的 CallAdapter

    • 使用时需要在Gradle添加依赖:
    网络请求适配器Gradle依赖
    guava com.squareup.retrofit2:adapter-guava:2.0.2
    Java8 com.squareup.retrofit2:adapter-java8:2.0.2
    rxjava com.squareup.retrofit2:adapter-rxjava:2.0.2

    步骤5:创建 网络请求接口实例

    1    // 创建 网络请求接口 的实例
    2         GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
    3 
    4         //对 发送请求 进行封装
    5         Call<Reception> call = request.getCall();

    步骤6:发送网络请求(异步 / 同步)

    封装了 数据转换、线程切换的操作

     1 //发送网络请求(异步)
     2         call.enqueue(new Callback<Translation>() {
     3             //请求成功时回调
     4             @Override
     5             public void onResponse(Call<Translation> call, Response<Translation> response) {
     6                 //请求处理,输出结果
     7                 response.body().show();
     8             }
     9 
    10             //请求失败时候的回调
    11             @Override
    12             public void onFailure(Call<Translation> call, Throwable throwable) {
    13                 System.out.println("连接失败");
    14             }
    15         });
    16 
    17 // 发送网络请求(同步)
    18 Response<Reception> response = call.execute();

    步骤7:处理返回数据

    通过response类的 body()对返回的数据进行处理

     1 //发送网络请求(异步)
     2         call.enqueue(new Callback<Translation>() {
     3             //请求成功时回调
     4             @Override
     5             public void onResponse(Call<Translation> call, Response<Translation> response) {
     6                 // 对返回数据进行处理
     7                 response.body().show();
     8             }
     9 
    10             //请求失败时候的回调
    11             @Override
    12             public void onFailure(Call<Translation> call, Throwable throwable) {
    13                 System.out.println("连接失败");
    14             }
    15         });
    16 
    17 // 发送网络请求(同步)
    18   Response<Reception> response = call.execute();
    19   // 对返回数据进行处理
    20   response.body().show();

    4. 实例讲解

    接下来,我将用两个实例分别对 Retrofit GET方式 和 POST方式进行 网络请求 讲解。

    4.1 实例1

    • 实现功能:将中文翻译成英文
    • 实现方案:采用Get方法对 金山词霸API 发送网络请求 

      采用 Gson 进行数据解析


    金山词典

    • 步骤说明

    步骤1:添加Retrofit库的依赖 
    步骤2:创建 接收服务器返回数据 的类 
    步骤3:创建 用于描述网络请求 的接口 
    步骤4:创建 Retrofit 实例 
    步骤5:创建 网络请求接口实例 并 配置网络请求参数 
    步骤6:发送网络请求(采用最常用的异步方式)

    封装了 数据转换、线程切换的操作

    步骤7: 处理服务器返回的数据

    接下来,我们一步步进行讲解。

    • 具体使用

    步骤1:添加Retrofit库的依赖

    1. 在 Gradle加入Retrofit库的依赖

    由于Retrofit是基于OkHttp,所以还需要添加OkHttp库依赖

    build.gradle

    1 dependencies {
    2     compile 'com.squareup.retrofit2:retrofit:2.0.2'
    3     // Retrofit库
    4     compile 'com.squareup.okhttp3:okhttp:3.1.2'
    5     // Okhttp库
    6   }

    2. 添加 网络权限 
    AndroidManifest.xml

    <uses-permission android:name="android.permission.INTERNET"/>

    步骤2:创建 接收服务器返回数据 的类

    • 金山词霸API 的数据格式说明如下:
     1 // URL模板
     2 http://fy.iciba.com/ajax.php
     3 
     4 // URL实例
     5 http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world
     6 
     7 // 参数说明:
     8 // a:固定值 fy
     9 // f:原文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
    10 // t:译文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
    11 // w:查询内容

    API格式说明

    • 根据 金山词霸API 的数据格式,创建 接收服务器返回数据 的类:

    Translation.java

     1 public class Translation {
     2         private int status;
     3 
     4     private content content;
     5     private static class content {
     6         private String from;
     7         private String to;
     8         private String vendor;
     9         private String out;
    10         private int errNo;
    11     }
    12 
    13     //定义 输出返回数据 的方法
    14     public void show() {
    15         System.out.println(status);
    16 
    17         System.out.println(content.from);
    18         System.out.println(content.to);
    19         System.out.println(content.vendor);
    20         System.out.println(content.out);
    21         System.out.println(content.errNo);
    22     }
    23 }

    步骤3:创建 用于描述网络请求 的接口

    采用 注解 描述 网络请求参数。 
    GetRequest_Interface.java

    1 public interface GetRequest_Interface {
    2 
    3  @GET("ajax.php?a=fy&f=auto&t=auto&w=hello%20world")
    4     Call<Translation> getCall();
    5     // 注解里传入 网络请求 的部分URL地址
    6     // Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里
    7     // 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略
    8     // getCall()是接受网络请求数据的方法
    9 }

    接下来的步骤均在GetRequest.java内实现(看注释)

    步骤4:创建Retrofit对象 
    步骤5:创建 网络请求接口 的实例 
    步骤6:发送网络请求

    以最常用的 异步请求 为例

    步骤7:处理返回数据

    GetRequest.java

     1 public class GetRequest extends AppCompatActivity {
     2 
     3     @Override
     4     protected void onCreate(Bundle savedInstanceState) {
     5         super.onCreate(savedInstanceState);
     6         setContentView(R.layout.activity_main);
     7 
     8         request();
     9         // 使用Retrofit封装的方法
    10     }
    11     public void request() {
    12 
    13         //步骤4:创建Retrofit对象
    14         Retrofit retrofit = new Retrofit.Builder()
    15                 .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
    16                 .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
    17                 .build();
    18 
    19         // 步骤5:创建 网络请求接口 的实例
    20         GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
    21 
    22         //对 发送请求 进行封装
    23         Call<Translation> call = request.getCall();
    24 
    25         //步骤6:发送网络请求(异步)
    26         call.enqueue(new Callback<Translation>() {
    27             //请求成功时回调
    28             @Override
    29             public void onResponse(Call<Translation> call, Response<Translation> response) {
    30                 // 步骤7:处理返回的数据结果
    31                 response.body().show();
    32             }
    33 
    34             //请求失败时回调
    35             @Override
    36             public void onFailure(Call<Translation> call, Throwable throwable) {
    37                 System.out.println("连接失败");
    38             }
    39         });
    40     }
    41 }

    由于此处采用了 Gson 解析,所以需要在 Gradle加入依赖 
    build.gradle

    compile 'com.squareup.retrofit2:converter-gson:2.0.2'

    运行结果

    运行结果

    Demo地址

    Carson_Ho的Github:https://github.com/Carson-Ho/RetrofitDemo


    4.2 实例2

    • 实现的功能:将 英文 翻译成 中文
    • 实现方法:采用Post方法对 有道API 发送网络请求 

      采用 Gson 进行数据解析


    有道翻译

    • 使用步骤

    步骤1:添加Retrofit库的依赖 
    步骤2:创建 接收服务器返回数据 的类 
    步骤3:创建 用于描述网络请求 的接口 
    步骤4:创建 Retrofit 实例 
    步骤5:创建 网络请求接口实例 并 配置网络请求参数 
    步骤6:发送网络请求(采用最常用的异步方式)

    封装了 数据转换、线程切换的操作

    步骤7: 处理服务器返回的数据

    接下来,我们一步步进行Retrofit的使用。

    • 具体使用

    步骤1:添加Retrofit库的依赖

    1. 在 Gradle加入Retrofit库的依赖

    由于Retrofit是基于OkHttp,所以还需要添加OkHttp库依赖

    build.gradle

    1 dependencies {
    2     compile 'com.squareup.retrofit2:retrofit:2.0.2'
    3     // Retrofit库
    4     compile 'com.squareup.okhttp3:okhttp:3.1.2'
    5     // Okhttp库
    6   }

    2. 添加 网络权限 
    AndroidManifest.xml

    <uses-permission android:name="android.permission.INTERNET"/>

    步骤2:创建 接收服务器返回数据 的类

    • API 的数据格式说明如下:
     1 // URL
     2 http://fanyi.youdao.com/translate
     3 
     4 // URL实例
     5 http://fanyi.youdao.com/translate?doctype=json&jsonversion=&type=&keyfrom=&model=&mid=&imei=&vendor=&screen=&ssid=&network=&abtest=
     6 
     7 
     8 // 参数说明
     9 // doctype:json 或 xml
    10 // jsonversion:如果 doctype 值是 xml,则去除该值,若 doctype 值是 json,该值为空即可
    11 // xmlVersion:如果 doctype 值是 json,则去除该值,若 doctype 值是 xml,该值为空即可
    12 // type:语言自动检测时为 null,为 null 时可为空。英译中为 EN2ZH_CN,中译英为 ZH_CN2EN,日译中为 JA2ZH_CN,中译日为 ZH_CN2JA,韩译中为 KR2ZH_CN,中译韩为 ZH_CN2KR,中译法为 ZH_CN2FR,法译中为 FR2ZH_CN
    13 // keyform:mdict. + 版本号 + .手机平台。可为空
    14 // model:手机型号。可为空
    15 // mid:平台版本。可为空
    16 // imei:???。可为空
    17 // vendor:应用下载平台。可为空
    18 // screen:屏幕宽高。可为空
    19 // ssid:用户名。可为空
    20 // abtest:???。可为空
    21 
    22 // 请求方式说明
    23 // 请求方式:POST
    24 // 请求体:i
    25 // 请求格式:x-www-form-urlencoded

    数据格式说明

    • 根据 有道API 的数据格式,创建 接收服务器返回数据 的类:

    Translation.java

     1 public class Translation1 {
     2 
     3     private String type;
     4     private int errorCode;
     5     private int elapsedTime;
     6     private List<List<TranslateResultBean>> translateResult;
     7 
     8     public String getType() {
     9         return type;
    10     }
    11 
    12     public void setType(String type) {
    13         this.type = type;
    14     }
    15 
    16     public int getErrorCode() {
    17         return errorCode;
    18     }
    19 
    20     public void setErrorCode(int errorCode) {
    21         this.errorCode = errorCode;
    22     }
    23 
    24     public int getElapsedTime() {
    25         return elapsedTime;
    26     }
    27 
    28     public void setElapsedTime(int elapsedTime) {
    29         this.elapsedTime = elapsedTime;
    30     }
    31 
    32     public List<List<TranslateResultBean>> getTranslateResult() {
    33         return translateResult;
    34     }
    35 
    36     public void setTranslateResult(List<List<TranslateResultBean>> translateResult) {
    37         this.translateResult = translateResult;
    38     }
    39 
    40     public static class TranslateResultBean {
    41         /**
    42          * src : merry me
    43          * tgt : 我快乐
    44          */
    45 
    46         public String src;
    47         public String tgt;
    48 
    49         public String getSrc() {
    50             return src;
    51         }
    52 
    53         public void setSrc(String src) {
    54             this.src = src;
    55         }
    56 
    57         public String getTgt() {
    58             return tgt;
    59         }
    60 
    61         public void setTgt(String tgt) {
    62             this.tgt = tgt;
    63         }
    64     }
    65 
    66 }

    步骤3:创建 用于描述网络请求 的接口

    采用 注解 描述 网络请求参数。

    PostRequest_Interface.java

    1 public interface PostRequest_Interface {
    2 
    3     @POST("translate?doctype=json&jsonversion=&type=&keyfrom=&model=&mid=&imei=&vendor=&screen=&ssid=&network=&abtest=")
    4     @FormUrlEncoded
    5     Call<Translation1> getCall(@Field("i") String targetSentence);
    6     //采用@Post表示Post方法进行请求(传入部分url地址)
    7     // 采用@FormUrlEncoded注解的原因:API规定采用请求格式x-www-form-urlencoded,即表单形式
    8     // 需要配合@Field 向服务器提交需要的字段
    9 }

    接下来的步骤均在PostRequest.java内实现(看注释)

    步骤4:创建Retrofit对象 
    步骤5:创建 网络请求接口 的实例 
    步骤6:发送网络请求

    以最常用的 异步请求 为例

    步骤7:处理返回数据

    PostRequest.java

     1 public class PostRequest extends AppCompatActivity {
     2 
     3 
     4     @Override
     5     protected void onCreate(Bundle savedInstanceState) {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_main);
     8 
     9         request();
    10     }
    11     public void request() {
    12 
    13         //步骤4:创建Retrofit对象
    14         Retrofit retrofit = new Retrofit.Builder()
    15                 .baseUrl("http://fanyi.youdao.com/") // 设置 网络请求 Url
    16                 .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
    17                 .build();
    18 
    19         // 步骤5:创建 网络请求接口 的实例
    20         PostRequest_Interface request = retrofit.create(PostRequest_Interface.class);
    21 
    22         //对 发送请求 进行封装(设置需要翻译的内容)
    23         Call<Translation1> call = request.getCall("I love you");
    24 
    25         //步骤6:发送网络请求(异步)
    26         call.enqueue(new Callback<Translation1>() {
    27 
    28             //请求成功时回调
    29             @Override
    30             public void onResponse(Call<Translation1> call, Response<Translation1> response) {
    31                 // 步骤7:处理返回的数据结果:输出翻译的内容
    32                 System.out.println(response.body().getTranslateResult().get(0).get(0).getTgt());
    33             }
    34 
    35             //请求失败时回调
    36             @Override
    37             public void onFailure(Call<Translation1> call, Throwable throwable) {
    38                 System.out.println("请求失败");
    39                 System.out.println(throwable.getMessage());
    40             }
    41         });
    42     }
    43 
    44 
    45 }

    由于此处采用了 Gson 解析,所以需要在 Gradle 加入依赖 
    build.gradle

    compile 'com.squareup.retrofit2:converter-gson:2.0.2'

    运行结果

    运行结果

    Demo地址

    Carson_Ho的Github:https://github.com/Carson-Ho/RetrofitDemo


    5. Retrofit 的拓展使用

    • Retrofit的使用场景非常丰富,如支持RxJavaPrototocobuff
    • 具体设置也非常简单 & 方便:
    <-- 主要在创建Retrofit对象中设置 -->
    1 Retrofit retrofit = new Retrofit.Builder()
    2   .baseUrl(""http://fanyi.youdao.com/"")
    3   .addConverterFactory(ProtoConverterFactory.create()) // 支持Prototocobuff解析
    4   .addConverterFactory(GsonConverterFactory.create()) // 支持Gson解析
    5   .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava
    6   .build();
    
    

    具体关于 RxJava的使用这里就不展开,请期待下篇关于 Rxjava的文章。

    转自:https://blog.csdn.net/carson_ho/article/details/73732076

  • 相关阅读:
    我的浏览器收藏夹分类
    我的浏览器收藏夹分类
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
  • 原文地址:https://www.cnblogs.com/zl1991/p/8744228.html
Copyright © 2020-2023  润新知