為替APIを使ってRetrofit2+RxAndroidで通信を試してみたいと思います。
内容としてはUSDからJPYに変換したレートを受け取りTextViewに表示するだけです。
使うAPI: http://fixer.io/ なかなか便利そうですね。
今回の実際のリクエストです。http://api.fixer.io/latest?base=USD&symbols=JPY
下記のように1件JPYのレートが入っています。
{
base: "USD",
date: "2016-11-01",
rates: {
JPY: 104.83
}
}
まずはappのbuild.gradleの設定から
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
// 追加
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
}
AndroidManifest.xmlにインターネットパーミッションを1行追加
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kojimation.com.retrofitsample">
<!-- インターネットパーミッション追加 -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
為替レートを取得するAPIの作成
rxじゃないObservableをimportしないように注意
public interface ExchangeRateApi {
String URL = "/latest";
@GET(URL)
Observable<ExchangeRateResponse> getExchangeRate(@Query("base") String base,
@Query("symbols") String symbols);
}
APIから返って来るレスポンスのオブジェクトを作成
public class ExchangeRateResponse {
private String base;
private String date;
private CountryCode rates;
public String getBase() {
return base;
}
public String getDate() {
return date;
}
public CountryCode getRates() {
return rates;
}
}
public class CountryCode {
private float JPY;
public float getJPY() {
return JPY;
}
}
MainActivityのxmlにTextViewを1つ追加
<?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:id="@+id/activity_main"
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="kojimation.com.retrofitsample.MainActivity">
<TextView
android:id="@+id/txt_jpy"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
MainActivityから使ってみる
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = new Retrofit.Builder()
// エンドポイントの設定
.baseUrl("http://api.fixer.io")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
retrofit.create(ExchangeRateApi.class)
// USドルからJPYに絞り込むクエリ
.getExchangeRate("USD", "JPY")
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ExchangeRateResponse>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.d("通信 -> ", "失敗" + e.toString());
}
@Override
public void onNext(ExchangeRateResponse exchangeRateResponse) {
Log.d("通信 -> ", "成功");
TextView textView = (TextView) findViewById(R.id.txt_jpy);
textView.setText("JPY: " + String.valueOf(exchangeRateResponse.getRates().getJPY()));
}
});
}
}
もう少し便利にしてみる
先ほどのbuild.gradleに2行追加
dependencies {
// 追加
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
// さらに追加
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
}
Okhttpクライアントを作成し、追加。
今回はログを追加してみる。
他にもヘッダーの設定等、色々追加できる。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// okhttpクライアントを作成
OkHttpClient okHttpclient = new OkHttpClient.Builder()
// ヘッダーを追加できるようにする
.addInterceptor(new RequestHeaderInterceptor())
// ログを出す
.addInterceptor(loggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
// エンドポイントの設定
.baseUrl("http://api.fixer.io")
// okhttpクライアントを追加
.client(okHttpclient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
retrofit.create(ExchangeRateApi.class)
// USドルからJPYに絞り込むクエリ
.getExchangeRate("USD", "JPY")
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ExchangeRateResponse>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.d("通信 -> ", "失敗" + e.toString());
}
@Override
public void onNext(ExchangeRateResponse exchangeRateResponse) {
Log.d("通信 -> ", "成功");
TextView textView = (TextView) findViewById(R.id.txt_jpy);
textView.setText("JPY: " + String.valueOf(exchangeRateResponse.getRates().getJPY()));
}
});
}
// ヘッダーのクラス
public class RequestHeaderInterceptor implements Interceptor {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
final Request.Builder builder = chain.request().newBuilder();
builder.addHeader("HEADER", "VALUE");
return chain.proceed(builder.build());
}
}
}
以上で終わりですが、さらににDagger2を加えたのも追記しておきます。
Dagger2 + Retrofit2 + RxAndroidで通信してみる
http://qiita.com/MuuKojima/items/8088b43876dc8d3d1745
Dagger2導入
http://qiita.com/MuuKojima/items/51cd6c1e59479cdcc2f4