一篇文章帶你走通 OkHttp+Retrofit+Rxjava

一篇文章帶你走通 OkHttp+Retrofit+Rxjava

@(Android)[android]

首先說明以下爲什麼要把這3個東西放在一起,其實主要是想介紹 Retrofit ,當時網上很多文章上來就是各種用法,對 我們剛剛接觸框架的人不太友好,所以想寫這篇文章來展示一下它們之間到底有什麼關聯。

Retrofit 我們知道是一個現在非常流行的網絡請求庫,它流行的關鍵在於它非常好使用,對Http請求做了封裝,讓我們使用起來更加方便,並且還提供了基於Anotation的 Rest風格的請求方式,如果使用過SpringMVC的人就能感覺到,這兩者結合起來,可以後臺和客戶端開發契合得更好。

OkHttp 是 Retrofit 底層使用的Http請求庫,都是 Square 公司的開源產品。OkHttp 和 Android中的 ,HttpUriConneciton纔是一級的產品,而Retrofit 底層使用作爲Http通信的工具的就是 OkHttp。

RxJava 其實和 Retrofit 並沒有什麼關係,但是由於它流式編程的思想,豐富的操作符,線程的任意切換等優點廣受大家的喜愛。特別是用在像做網絡請求這樣比較繁瑣的邏輯處理中,更能顯示出它的威力,所以將RxJava和Retrofit結合起來,威力無比強大。

但是我也剛剛接觸,學習總結以下,所以這篇文章也只針對新手而已,大神請自行繞過。

參考網站

OkHttp官網
Okio官網
Retrofit官網

OkHttp部分

要使用OkHttp,首先需要添加它的依賴,同時OkHttp又依賴了Okio,所以需要同時添加Okio的依賴。

OkHttp依賴

maven:

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>3.6.0</version>
</dependency>

gradle:

compile 'com.squareup.okhttp3:okhttp:3.6.0'

Okio依賴

maven:

<dependency>
    <groupId>com.squareup.okio</groupId>
    <artifactId>okio</artifactId>
    <version>1.11.0</version>
</dependency>

gradle:

compile 'com.squareup.okio:okio:1.11.0'

使用OkHttp下載圖片例子

class DownloadImageThread extends Thread {
    private String url;
    private ImageView imageView;

    public DownloadImageThread(String url, ImageView imageView) {
      this.url = url;
      this.imageView = imageView;
    }

    @Override
    public void run() {
      OkHttpClient client = new OkHttpClient();
      Request request = new Request.Builder()
          .url(url)
          .build();

      try {
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
          final Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
          runOnUiThread(new Runnable() {
            @Override
            public void run() {
              imageView.setImageBitmap(bitmap);
            }
          });
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

Retrofit部分

Retrofit依賴

Maven:

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.1.0</version>
</dependency>

Gradle:

compile 'com.squareup.retrofit2:retrofit:2.1.0'

Gson依賴

compile 'com.google.code.gson:gson:2.3.1'

返回數據轉換器依賴

在Retrofit中將轉換器稱爲 Converters,它的作用就是用來添加對返回數據的轉換支持。例如的是String 就需要 scalar,如果是 json,需要使用 gson 等。後面的代碼中可以看到

  • Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars:2.1.0
  • Gson: com.squareup.retrofit2:converter-gson:2.1.0
  • Jackson: com.squareup.retrofit2:converter-jackson:{最新版本號}
  • Moshi: com.squareup.retrofit2:converter-moshi:{最新版本號}
  • Protobuf: com.squareup.retrofit2:converter-protobuf:{最新版本號}
  • Wire: com.squareup.retrofit2:converter-wire:{最新版本號}
  • Simple XML: com.squareup.retrofit2:converter-simplexml:{最新版本號}

例子所有依賴

接下來兩個例子將展示怎麼使用Retrofit請求Github api的數據。

dependencies {
    //...
    compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.google.code.gson:gson:2.3.1'
}

請求String數據例子

GitHubService.java 定義發出Http請求的接口。兩個接口,一個返回String,一個返回GitModel(Github返回的Json數據的Pojo類)

public interface GitHubService {

  String BASEURL = "https://api.github.com";

  @GET("users/{user}")
  Call<String> getData(@Path("user") String user);

  @GET("users/{user}")
  Call<GitModel> getUserInfo(@Path("user") String user);
}

GitModel.java 注意:這裏省略了 getters 和 setters,還需要 Gson 支持

public class GitModel {
  @Expose
  private String login;
  @Expose
  private Integer id;
  @SerializedName("avatar_url")
  @Expose
  private String avatarUrl;
  @SerializedName("gravatar_id")
  @Expose
  private String gravatarId;
  @Expose
  private String url;
  @SerializedName("html_url")
  @Expose
  private String htmlUrl;
  @SerializedName("followers_url")
  @Expose
  private String followersUrl;
  @SerializedName("following_url")
  @Expose
  private String followingUrl;
  @SerializedName("gists_url")
  @Expose
  private String gistsUrl;
  @SerializedName("starred_url")
  @Expose
  private String starredUrl;
  @SerializedName("subscriptions_url")
  @Expose
  private String subscriptionsUrl;
  @SerializedName("organizations_url")
  @Expose
  private String organizationsUrl;
  @SerializedName("repos_url")
  @Expose
  private String reposUrl;
  @SerializedName("events_url")
  @Expose
  private String eventsUrl;
  @SerializedName("received_events_url")
  @Expose
  private String receivedEventsUrl;
  @Expose
  private String type;
  @SerializedName("site_admin")
  @Expose
  private Boolean siteAdmin;
  @Expose
  private String name;
  @Expose
  private String company;
  @Expose
  private String blog;
  @Expose
  private String location;
  @Expose
  private String email;
  @Expose
  private Boolean hireable;
  @Expose
  private Object bio;
  @SerializedName("public_repos")
  @Expose
  private Integer publicRepos;
  @SerializedName("public_gists")
  @Expose
  private Integer publicGists;
  @Expose
  private Integer followers;
  @Expose
  private Integer following;
  @SerializedName("created_at")
  @Expose
  private String createdAt;
  @SerializedName("updated_at")
  @Expose
  private String updatedAt;

  // Getters
  // ...

  // Setters
  // ...
}

MainActivity.java

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(GitHubService.BASEURL)
    //添加String支持
    .addConverterFactory(ScalarsConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);
Call<String> call = service.getData(username);//username 可以自己傳入github的用戶名

// 異步請求
call.enqueue(new Callback<String>() {
  @Override
  public void onResponse(Call<String> call, Response<String> response) {
    // 處理返回數據
    if (response.isSuccessful()) {
      Log.d(TAG, "onResponse: " + response.body());
    }
  }
  @Override
  public void onFailure(Call<String> call, Throwable t) {
    Log.d(TAG, "onFailure: 請求數據失敗");
  }
});

請求Json數據例子

如果是Json數據,使用Gson自動解析

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(GitHubService.BASEURL)
    // 添加Json轉換器支持
    .addConverterFactory(GsonConverterFactory.create())
    .build();
GitHubService service = retrofit.create(GitHubService.class);
Call<GitModel> call = service.getUserInfo(username);//username 可填入自己Github賬號用戶名
call.enqueue(new Callback<GitModel>() {
  @Override
  public void onResponse(Call<GitModel> call, Response<GitModel> response) {
    if (response.isSuccessful()) {
      Log.d(TAG, "onResponse: " + response.body().getName());
    }
  }
  @Override
  public void onFailure(Call<GitModel> call, Throwable t) {
    Log.d(TAG, "onFailure: " + t.getMessage());
  }
});

使用 ResponseBody

當然,我們還可以直接使用 ResponseBody,還記得前面我們介紹過OkHttp,其實Retrofit 底層使用的 也是OkHttp,所以我們的請求完全也可以使用 OkHttp 的 Response 對象 中的 ResponseBody 對象來處理返回數據。

GitHubService.java

public interface GitHubService {
  String BASEURL = "https://api.github.com";

  //...

  @GET("users/{user}")
  Call<ResponseBody> getResponseBody(@Path("user") String user);
}

獲取 ResponseBody,然後處理方法就和 OkHttp 一樣了

GitHubService service = retrofit.create(GitHubService.class);
Call<ResponseBody> call = service.getResponseBody(username);
call.enqueue(new Callback<ResponseBody>() {
  @Override
  public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
    if(response.isSuccessful()){
      try {
        Log.d(TAG, "onResponse: "+response.body().string());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  @Override
  public void onFailure(Call<ResponseBody> call, Throwable t) {
    Log.d(TAG, "onFailure: ");
  }
});

使用RxJava

要使用RxJava和Retrofit的結合,首先我們要添加要給依賴

compile 'io.reactivex:rxjava:1.1.7'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

再添加一個新的訪問數據方法

public interface GitHubService {
  String BASEURL = "https://api.github.com";

  //...
  @GET("users/{user}")
  Observable<GitModel> rxUser(@Path("user") String user);
}

使用Rxjava訪問

public void rxRetrofit(String username) {
  Retrofit retrofit = new Retrofit.Builder()
      .baseUrl(GitHubService.BASEURL)
      .addConverterFactory(GsonConverterFactory.create())
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
      .build();

  GitHubService service = retrofit.create(GitHubService.class);
  Observable<GitModel> obserable = service.rxUser(username);
  obserable
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(new Subscriber<GitModel>() {
        @Override
        public void onCompleted() {
          Log.d(TAG, "onCompleted: ");
        }

        @Override
        public void onError(Throwable e) {
          Log.d(TAG, "onError: " + e.getMessage());
        }

        @Override
        public void onNext(GitModel gitModel) {
          Log.d(TAG, "onNext: " + gitModel.getName());
        }
      });
}

在使用時發現代碼不但沒有減少,而且增多了,其實不然。這只是展示的一個最基本的例子,RxJava的強大之處在於它流式編程的思想,強大的操作符,以及線程之間的切換。當我們有比較複雜的邏輯的時候,它的強大就顯現出來了,這裏只是爲了演示用法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章