[Android] OkHttp3 を使ってみた / Get Post のサンプルアプリ
📅 November 07, 2016
•⏱️5 min read
はじめに
Apache Http Client が API 22 から deprecated になったことを受け、 通信ライブラリとして OkHttp を選択されているようですね。 そんなわけで試しに使ってみたメモです。
導入
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.+'
}
おなじみの gradle ファイルに書くだけ。 本記事時点で、OkHttp のバージョンは、3.4.2 でした。
サンプルアプリ
Get ボタンと Post ボタンを用意して OkHttp を使って各メソッドを実行し、 レスポンスを表示するサンプルアプリです。
Get のときは、お天気Webサービス(Livedoor Weather Web Service / LWWS) の API を叩いてみます。 サンプルとして東京の天気予報をリクエストします。 http://weather.livedoor.com/forecast/webservice/json/v1?city=130010 クエリの city には、東京の番号である 130010 を入れます。
GETTESTボタンをタップすると Response には、APIが返す JSON データが表示されます。 Description には指定した JSON オブジェクトをひとつ表示しています。 このサンプルでは、例として配列 pinpointLocations の1番目のオブジェクトの キー "name" の値を表示します。 東京における1番目のピンポイントロケーションは千代田区ですので、 "千代田区" と表示されるはずです。
Post のときは、キーと対応する値を一緒に送信します。 確認には、HTTPアクセス POST送信 テスト確認用ページ こちらのテストサイト様を使用させていただきました。 POSTTESTボタンをタップするとレスポンスとしてHTMLがそのまま表示されます。 そのHTMLの中に送信したキーと対応する値を確認できるはずです。
ソースコード
■ MainActivity.java
// import 省略
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView textViewRes;
private TextView textViewDes;
private Button buttonGetTest;
private Button buttonPostTest;
private String res = "";
private String des = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewRes = (TextView) findViewById(R.id.tv_res);
textViewDes = (TextView) findViewById(R.id.tv_des);
buttonGetTest = (Button) findViewById(R.id.btn_get_test);
buttonPostTest = (Button) findViewById(R.id.btn_post_test);
buttonGetTest.setOnClickListener(this);
buttonPostTest.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_get_test: getTest(); break;
case R.id.btn_post_test: postTest(); break;
default: break;
}
}
// GET
private void getTest() {
Request request = new Request.Builder()
.url("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010") // 130010->東京
.get()
.build();
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
failMessage();
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
res = response.body().string();
try {
JSONObject resJson = new JSONObject(res);
JSONArray weathers = resJson.getJSONArray("pinpointLocations"); // 例として "pinpointLocations" を取り出す
JSONObject weather = weathers.getJSONObject(0); // 2番目のオブジェクトにアクセスしたい場合は"1"
String description = weather.getString("name"); // 例として "name" を取り出す
des = description;
// UI反映
runOnUiThread(new Runnable() {
public void run() {
textViewRes.setText(res);
textViewDes.setText(des);
}
});
} catch(JSONException e) {
failMessage();
e.printStackTrace();
}
}
});
}
// POST
private void postTest() {
RequestBody formBody = new FormBody.Builder()
.add("tokyo", "130010")
.add("osaka", "270000")
.add("name", "nanashinogonbei")
.add("action", "hoge")
.add("value", "fuga")
.build();
Request request = new Request.Builder()
.url("http://www.muryou-tools.com/test/aaaa.php") // HTTPアクセス POST送信 テスト確認用ページ
.post(formBody)
.build();
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
failMessage();
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
res = response.body().string();
runOnUiThread(new Runnable() {
public void run() {
textViewRes.setText(res);
textViewDes.setText("No Data");
}
});
}
});
}
private void failMessage() {
runOnUiThread(new Runnable() {
public void run() {
textViewRes.setText("onFailure");
textViewDes.setText("No Data");
}
});
}
}
onResponse() など各コールバックは、UIスレッドで実行されません。 そのため、表示を更新するには runOnUIThread() などを実行する必要があります。
■ activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.mdw-note.okhttptest.MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/scrollView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="getTest"
android:id="@+id/btn_get_test"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="postTest"
android:id="@+id/btn_post_test"
android:layout_toRightOf="@+id/btn_get_test"
android:layout_toEndOf="@+id/btn_get_test" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Response"
android:id="@+id/tv_title_res"
android:layout_below="@+id/btn_get_test"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="No Data"
android:id="@+id/tv_res"
android:layout_below="@+id/tv_title_res"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Description"
android:id="@+id/tv_title_des"
android:layout_below="@+id/tv_res"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="No Data"
android:id="@+id/tv_des"
android:layout_below="@+id/tv_title_des"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</ScrollView>
</RelativeLayout>
実行結果
Get, Post それぞれレスポンスが表示されていることが確認できます。
Get のときの Description もきちんと"千代田区"です。
OkHttp のお試しサンプルアプリでした。 ではでは。