1はじめに
Retrofitは、Squareが開発したAndroidのHTTPネットワークリクエスト用のフレームワークです。公式ウェブサイトはhttps://square.github.io/retrofit/です。最下層はOkHttpに基づいています。つまり、RetrofitはさらにOkHttpをカプセル化します。レトロフィットの最大の特徴はシンプルさと使いやすさであり、多数のランタイムアノテーションを使用して機能を提供します。
2 クイックスタート
サーバーインターフェイスがあるとします:https : //api.xx.com/url.json?id=123、および要求後の戻り値は
[
{
"app_name": "今日头条",
"package_name": "com.ss.android.article.news"
},
{
"app_name": "腾讯新闻",
"package_name": "com.tencent.news"
},
{
"app_name": "凤凰新闻",
"package_name": "com.ifeng.news2"
}
]
コードでネットワークリクエストを行い、返された結果をAppInfoオブジェクトに変換する必要があります。AppInfoクラスコードは次のとおりです。
AppInfo.java
public class AppInfo {
private String app_name;
private String package_name;
@Override
public String toString() {
return "{app_name:" + app_name + ",package_name:" + package_name + "}";
}
}
build.gradleにサポートライブラリの依存関係を追加します。
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
}
AndroidManifest.xmlでネットワークリクエスト権限を宣言します。
<uses-permission android:name="android.permission.INTERNET"/>
したがって、Retrofitを使用して、次のようなネットワーク要求コードを作成します。
private void getRequest() {
Retrofit retorfit = new Retrofit.Builder()
.baseUrl("https://api.xx.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
AppInfoService appInfoService = retorfit.create(AppInfoService.class);
Call<List<AppInfo>> call = appInfoService.getAppInfoList(123);
call.enqueue(new Callback<List<AppInfo>>() {
@Override
public void onResponse(Call<List<AppInfo>> call, Response<List<AppInfo>> response) {
List<AppInfo> appInfos = response.body();
Log.e("zyx", appInfos.toString());
Log.e("zyx", "当前线程:" + Thread.currentThread().getName());
}
@Override
public void onFailure(Call<List<AppInfo>> call, Throwable t) {
Log.e("zyx", t.toString());
Log.e("zyx", "当前线程:" + Thread.currentThread().getName());
}
});
}
public interface AppInfoService {
@GET("url.json")
Call<List<AppInfo>> getAppInfoList(@Query("id") int id);
}
コードでgetRequestメソッドを実行し、プログラムを実行すると、次の結果の出力が表示され、メインスレッドでもコールバックが実行されます。
2019-12-04 19:27:23.209 30842-30842/com.zyx.myapplication E/zyx: [{app_name:今日头条,package_name:com.ss.android.article.news}, {app_name:腾讯新闻,package_name:com.tencent.news}, {app_name:凤凰新闻,package_name:com.ifeng.news2}]
2019-12-04 19:27:23.212 30842-30842/com.zyx.myapplication E/zyx: 当前线程:main
3はじめに
3.1ライブラリの依存関係とコンバーター
Rerofitライブラリを使用するには、build.gradleで依存関係を構成する必要があります。
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
}
上記の例では、Rerofitライブラリに加えて、gsonライブラリが追加されています。実際、gsonライブラリはオプションです。デフォルトでは、RetrofitはHTTP応答結果をOkHttpのResponseBody型にのみ逆シリアル化でき、そのRequsetBody型は@Bodyのみ受け入れることができます(後述)。ただし、他のコンバーターを追加して、addConverterFactoryメソッドを介して他のタイプをサポートできます。次の依存関係パッケージを追加することで、そのシリアル化操作をサポートできます。
- Gson:com.squareup.retrofit2:converter-gson
- ジャクソン:com.squareup.retrofit2:converter-jackson
- モシ:com.squareup.retrofit2:converter-moshi
- プロトブフ:com.squareup.retrofit2:converter-protobuf
- ワイヤー:com.squareup.retrofit2:converter-wire
- 単純なXML:com.squareup.retrofit2:converter-simplexml
もちろん、Converter.Factoryから継承するクラスを作成し、responseBodyConverterメソッドとrequestBodyConverterメソッドを実装して、アダプターを追加するときにaddConverterFactoryを使用してインスタンスを追加する限り、独自のコンバーターをカスタム方法で作成することもできます。
3.2リクエストメソッドのアノテーション
上記の例のAppInfoServiceから、getAppInfoListメソッドで@GETアノテーションが定義されていることがわかります実際には、アノテーションを使用して多くのRefitを実行しています。HTTPリクエストメソッドアノテーションには、GET、POST、PUT、DELETE、HEAD、PATCH、OPTIONS、HTTPの 8種類があります。このうち、最初の7つのタイプはそれぞれHTTPリクエストメソッドに対応し、最後のタイプのHTTPは一般的なアノテーションであり、パラメーターで置き換えることができます。として使用:
@HTTP(method = "GET", path = " url.json", hasBody = false)
Call<List<AppInfo>> getAppInfoList();
method はリクエストのメソッドを示します。大文字と小文字が区別されることに注意してください
pathはネットワーク要求アドレスパスを 表します
hasBody は、リクエスト本文があるかどうかを示します
3.3リクエストヘッダーコメント
要求ヘッダーは2つありコメント:ヘッダーと ヘッダーを。違いは、前者は一般にファームウェアのリクエストヘッダーに使用され、複数のものを追加できることです;後者は一般に、メソッドのパラメーター入力として使用される非固定リクエストヘッダーに使用されます。
@Headers({"Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App"})
@GET("url.json")
Call<List<AppInfo>> getAppInfoList(@Header("Authorization") String authorization);
3.3パラメータの注釈
パラメータアノテーションには、Body、Path、Field、FieldMap、Part、PartMap、Query、QueryMap、Url などがあります。
3.3.1ボディ
PostリクエストのHTTPリクエストボディを送信するために使用されます。たとえば、GsonConverterFactoryが追加され、クラスオブジェクトに渡すことができます。
@POST("users/new")
Call<User> createUser(@Body User user);
3.3.2パス
URLのプレースホルダーとして使用され、次のように使用されます。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
3.3.3フィールドとFieldMap
Postリクエストに使用するときに、フォームの形式でパラメーターを渡すために使用されます。これは、@ FromUrlEncodedと組み合わせて使用する必要があります。
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@FieldMap Map<String, String> map);
3.3.4パーツとパーツマップ
Postリクエストに使用するときに、フォームの形式でパラメーターをポストするために使用されます。@ Fieldとは異なります。これは、より豊富なパラメータータイプを伝送できます。たとえば、ファイルをアップロードするときにデータストリームを伝送できます。
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
@Multipart
@PUT("user/photo")
Call<User> updateUser(@PartMap Map<String, RequestBody> map);
3.3.5クエリとクエリマップ
リクエストを取得するときにパラメーターを渡すために使用されます。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
3.3.6 URL
次のようなリクエストパスを指定するために使用されます。
@GET
Call<List<AppInfo>> getAppInfoList(@Url String url, @Query("id") int id);
3.4マーカー注釈
マークアップの注釈には、FormUrlEncoded、Multipart、Streamingの 3種類があります。
3.4.1 FormUrlEncoded
Postリクエストで使用する場合、リクエスト元のエンティティがFromフォームの場合、各キーと値のペアに@Fieldの注釈を付ける必要があるため、上記のようにFieldとFieldMapが導入されます。
3.4.2マルチパート
Postリクエストに使用する場合、リクエストエンティティには、ファイルのアップロード時に伝送できるデータストリームなどのパラメータタイプが豊富です。各Key-Valueペアには@Partアノテーションを付けて、上記のようにPartとPartMapを導入する必要があります。
3.4.3ストリーミング
通常、大きなファイルをダウンロードするときは、@ Streamingアノテーションを追加する必要があります。つまり、応答がバイトストリームの形式で返されるため、すべての大きなファイルがメモリに読み込まれるのを回避できます。
3.5同期および非同期
呼び出しオブジェクトは、同期または非同期でネットワーク要求を行うことができ、各オブジェクトは1回しか使用できません。複数回実行する場合は、clone()を呼び出して新しいオブジェクトを作成できます。また、Androidではコールバックがメインスレッドで実行され、JVMではコールバックはHTTPリクエストと同じスレッドで実行されることにも注意してください。
同期実行のサンプルコード:
try {
Response<List<AppInfo>> response = call.execute();
List<AppInfo> appInfos = response.body();
Log.e("zyx", appInfos.toString());
} catch (IOException e) {
e.printStackTrace();
}
非同期実行のサンプルコード:
call.enqueue(new Callback<List<AppInfo>>() {
@Override
public void onResponse(Call<List<AppInfo>> call, Response<List<AppInfo>> response) {
List<AppInfo> appInfos = response.body();
Log.e("zyx", appInfos.toString());
}
@Override
public void onFailure(Call<List<AppInfo>> call, Throwable t) {
Log.e("zyx", t.toString());
}
});
上記の同期コードと非同期コードを確認した後、なじみ深い感謝の気持ちをお持ちですか?Rerofitフレームワークの下部では元々OkHttpが使用されていたため、OkHttpの同期リクエストと非同期リクエストは同様のコードであることを以前に学びました。