Retrofit 简介

用于Android和Java平台的一款类型安全的HTTP客户端,通过一个Java接口实现HTTP请求对象,如下:

public interface Github {    @GET("/repos/{owner}/{repo}/contributors")    Call> contributors(            @Path("owner") String owner,            @Path("repo") String repo);}

Android 平台使用示例

步骤如下:

  • 添加 Retrofit 相关依赖库
//retrofit2 依赖库implementation 'com.squareup.retrofit2:retrofit:2.4.0'//Gson 数据解析器依赖库implementation 'com.squareup.retrofit2:converter-gson:2.4.0'//okhttp3 输出网络请求日志依赖库implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
  • 创建接收服务器返回数据对应的实体类
//创建接收服务器返回数据的类public class Contributor {    public final String login;    public final int contributions;    public Contributor(String login, int contributions) {        this.login = login;        this.contributions = contributions;    }}
  • 创建用于描述网络请求的接口
//创建用于网络请求的接口public interface Github {    @GET("/repos/{owner}/{repo}/contributors")    Call> contributors(            @Path("owner") String owner,            @Path("repo") String repo);}
  • *配置打印网络请求日志
HttpLoggingInterceptor loggingInterceptor;//打印网络请求相关日志loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {      @Override      public void log(String message) {           //打印retrofit日志           Log.i("retrofitLog: ", message);      }});loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//为了打印日志,需要配置OkHttpClientOkHttpClient client = new OkHttpClient.Builder()                .addInterceptor(loggingInterceptor)                .build();
  • 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()                .baseUrl(API_GITHUB_URL)                .client(client)                .addConverterFactory(GsonConverterFactory.create())                .build();
  • 创建网络请求接口实例
//创建网络接口实例Github github = retrofit.create(Github.class);//对发送请求进行封装Call> call = github.contributors("square", "retrofit");
  • 发送网络请求(异步 / 同步)并对返回数据进行处理
//发送同步请求时不能直接在UI线程进行,不然会报错:NetworkOnMainThreadException//发送请求,获取请求的数据List contributors = call.execute().body();StringBuilder result = new StringBuilder();for (Contributor contributor : contributors) {      result.append(contributor.login + " (" + contributor.contributions + ")\n");}Log.e("result", result.toString());

主要代码如下

  • MainActivity.java

    public class MainActivity extends AppCompatActivity {private TextView tv_request_result;public static final String API_GITHUB_URL = "https://api.github.com";HttpLoggingInterceptor loggingInterceptor;private Handler handler = new Handler(){    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        Bundle data = msg.getData();        String result = data.getString("result");        tv_request_result.setText(result);    }};@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    initView();    //打印网络请求相关日志    loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {        @Override        public void log(String message) {            //打印retrofit日志            Log.i("retrofitLog: ", message);        }    });    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);    new Thread(runnable).start(); //不能在UI线程中进行网络请求}private void initView() {    tv_request_result = (TextView) findViewById(R.id.tv_request_result);}//发送网络请求private String request() throws IOException {    //为了打印日志,需要配置okhttp    OkHttpClient client = new OkHttpClient.Builder()            .addInterceptor(loggingInterceptor)            .build();    //创建Retrofit对象    Retrofit retrofit = new Retrofit.Builder()            .baseUrl(API_GITHUB_URL)            .client(client)            .addConverterFactory(GsonConverterFactory.create())            .build();    //创建网络接口实例    Github github = retrofit.create(Github.class);    //对发送请求进行封装    Call> call = github.contributors("square", "retrofit");    //发送请求,获取请求的数据    List contributors = call.execute().body();    StringBuilder result = new StringBuilder();    for (Contributor contributor : contributors) {        result.append(contributor.login + " (" + contributor.contributions + ")\n");    }    Log.e("result", result.toString());    return result.toString();}//网络请求线程Runnable runnable = new Runnable() {    @Override    public void run() {        try {            String result = request();            Message msg = new Message();            Bundle data = new Bundle();            data.putString("result", result);            msg.setData(data);            handler.sendMessage(msg);        } catch (IOException e) {            Log.e("request_erro", e.toString());        }    }};}
  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent">    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent">        <TextView            android:id="@+id/tv_request_result"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textSize="20sp" />    ScrollView>LinearLayout>
  • 程序运行结果
  • 网络请求日志如下:
07-02 16:07:41.145 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: --> GET https://api.github.com/repos/square/retrofit/contributors http/1.1    --> END GET07-02 16:07:43.275 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: <-- 200 OK https://api.github.com/repos/square/retrofit/contributors (2129ms)    Server: GitHub.com    Date: Mon, 02 Jul 2018 08:07:45 GMT    Content-Type: application/json; charset=utf-8    Transfer-Encoding: chunked    Status: 200 OK    X-RateLimit-Limit: 60    X-RateLimit-Remaining: 30    X-RateLimit-Reset: 1530522209    Cache-Control: public, max-age=60, s-maxage=6007-02 16:07:43.276 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: Vary: Accept    ETag: W/"0313af265d6c3206fe7e38545918e2bf"    Last-Modified: Mon, 02 Jul 2018 07:42:01 GMT    X-GitHub-Media-Type: github.v3; format=json    Link: //api.github.com/repositories/892275/contributors?page=2>; rel="next", ; rel="last"    Access-Control-Expose-Headers: ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval    Access-Control-Allow-Origin: *    Strict-Transport-Security: max-age=31536000; includeSubdomains; preload    X-Frame-Options: deny    X-Content-Type-Options: nosniff    X-XSS-Protection: 1; mode=block    Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin    Content-Security-Policy: default-src 'none'    X-Runtime-rack: 0.075905    X-GitHub-Request-Id: 90E0:3CD2:61BDD85:BCDE66D:5B39DD5007-02 16:07:43.288 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: [{"login":"JakeWharton","id":66577,"node_id":"MDQ6VXNlcjY2NTc3","avatar_url":"https://avatars0.githubusercontent.com/u/66577?v=4","gravatar_id":"","url":"https://api.github.com/users/JakeWharton","html_url":"https://github.com/JakeWharton","followers_url":"https://api.github.com/users/JakeWharton/followers","following_url":"https://api.github.com/users/JakeWharton/following{/other_user}","gists_url":"https://api.github.com/users/JakeWharton/gists{/gist_id}","starred_url":"https://api.github.com/users/JakeWharton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JakeWharton/subscriptions","organizations_url":"https://api.github.com/users/JakeWharton/orgs","repos_url":"https://api.github.com/users/JakeWharton/repos","events_url":"https://api.github.com/users/JakeWharton/events{/privacy}","received_events_url":"https://api.github.com/users/JakeWharton/received_events","type":"User","site_admin":false,"contributions":911},{"login":"swankjesse","id":133019,"node_id":"MDQ6VXNlcjEzMzAxOQ==","avatar_url":"https://avatars3.githubusercontent.com/u/133019?v=4","gravatar_id":"","url":"https://api.github.com/users/swankjesse","html_url":"https://github.com/swankjesse","followers_url":"https://api.github.com/users/swankjesse/followers","following_url":"https://api.github.com/users/swankjesse/following{/other_user}","gists_url":"https://api.github.com/users/swankjesse/gists{/gist_id}","starred_url":"https://api.github.com/users/swankjesse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swankjesse/subscriptions","organizations_url":"https://api.github.com/users/swankjesse/orgs","repos_url":"https://api.github.com/users/swankjesse/repos","events_url":"https://api.github.com/users/swankjesse/events{/privacy}","received_events_url":"https://api.github.com/users/swankjesse/received_events","type":"User","site_admin":false,"contributions":224},{"login":"pforhan","id":331925,"node_id":"MDQ6VXNlcjMzMTkyNQ==","avatar_url":"https://avatars3.githubusercontent.com/u/331925?v=4","gravatar_id":"","url":"https://api.github.com/users/pforhan","html_url":"https://github.com/pforhan","followers_url":"https://api.github.com/users/pforhan/followers","following_url":"https://api.github.com/users/pforhan/following{/other_user}","gists_url":"https://api.github.com/users/pforhan/gists{/gist_id}","starred_url":"https://api.github.com/users/pforhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pforhan/subscriptions","organizations_url":"https://api.github.com/users/pforhan/orgs","repos_url":"https://api.github.com/users/pforhan/repos","events_url":"https://api.github.com/users/pforhan/events{/privacy}","received_events_url":"https://api.github.com/users/pforhan/received_events","type":"User","site_admin":false,"contributions":48},{"login":"eburke","id":63761,"node_id":"MDQ6VXNlcjYzNzYx","avatar_url":"https://avatars0.githubusercontent.com/u/63761?v=4","gravatar_id":"","url":"https://api.github.com/users/eburke","html_url":"https://github.com/eburke","followers_url":"https://api.github.com/users/eburke/followers","following_url":"https://api.github.com/users/eburke/following{/other_user}","gists_url":"https://api.github.com/users/eburke/gists{/gist_id}","starred_url":"https://api.github.com/users/eburke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eburke/subscriptions","organizations_url":"https://api.github.com/users/eburke/orgs","repos_url":"https://api.github.com/users/eburke/repos","events_url":"https://api.github.com/users/eburke/events{/privacy}","received_events_url":"https://api.github.com/users/eburke/received_events","type":"User","site_admin":false,"contributions":36},{"login":"dnkoutso","id":310370,"node_id":"MDQ6VXNlcjMxMDM3MA==","avatar_url":"https://avatars2.githubusercontent.com/u/310370?v=4","gravatar_id":"","url":"https://api.github.com/users/dnkoutso","html_url":"https://github.com/dnkoutso","followers_url":"https://api.github.com/users/dnkoutso/followers","following_url":"https://api.github.com/users/d    <-- END HTTP (28135-byte body)
  • 服务器返回数据示例
{    "login": "JakeWharton",    "id": 66577,    "node_id": "MDQ6VXNlcjY2NTc3",    "avatar_url": "https://avatars0.githubusercontent.com/u/66577?v=4",    "gravatar_id": "",    "url": "https://api.github.com/users/JakeWharton",    "html_url": "https://github.com/JakeWharton",    "followers_url": "https://api.github.com/users/JakeWharton/followers",    "following_url": "https://api.github.com/users/JakeWharton/following{/other_user}",    "gists_url": "https://api.github.com/users/JakeWharton/gists{/gist_id}",    "starred_url": "https://api.github.com/users/JakeWharton/starred{/owner}{/repo}",    "subscriptions_url": "https://api.github.com/users/JakeWharton/subscriptions",    "organizations_url": "https://api.github.com/users/JakeWharton/orgs",    "repos_url": "https://api.github.com/users/JakeWharton/repos",    "events_url": "https://api.github.com/users/JakeWharton/events{/privacy}",    "received_events_url": "https://api.github.com/users/JakeWharton/received_events",    "type": "User",    "site_admin": false,    "contributions": 911  }

更多相关文章

  1. android 创建桌面快捷方式 、插件
  2. AIR Native Extension的使用(Android)一 : 打包ane
  3. Android中判断网络功能是否可用
  4. Android的网络状态判断
  5. 创建android逐帧动画的两种方式
  6. 使用sencha cmd创建android应用
  7. Android(安卓)Paging组件Demo
  8. 【安卓笔记】android客户端与服务端交互的三种方式
  9. android 来电自动接听和自动挂断

随机推荐

  1. Android NDK开发之旅38--FFmpeg视频添加
  2. android面试-面试知识点总结
  3. selector选择器
  4. android 图片占用内存与什么有关
  5. Android中ScrollView嵌套WebView
  6. Android之应用资源
  7. Android studio4.0 解决导入包Error 报错
  8. android 当环境配置发生变化 例如语言 屏
  9. Android ActionBar中的按钮添加旋转动画
  10. eclipse 开发 android 快捷键!