LoginSignup
21
18

More than 5 years have passed since last update.

Dagger2 + Retrofit2 + RxAndroidで通信してみる

Last updated at Posted at 2016-11-10

為替APIを使ってDagger2 + Retrofit2 + RxAndroidで通信を試してみたいと思います。

基本的には、以前書いたものにDagger2を加えただけになります。
http://qiita.com/MuuKojima/items/01a0738e4c4d1879189c

今回の内容としてはUSDからJPYに変換した為替レートを受け取りTextViewに表示するだけです。
使うAPI: http://fixer.io/ なかなか便利そうですね。

実際のリクエストです。http://api.fixer.io/latest?base=USD&symbols=JPY
下記のように1件JPYのレートが入っています。

今回の例
{
    base: "USD",
    date: "2016-11-09",
    rates: {
    JPY: 103.92
    }
}

それでは、まずrootのbuild.gradleの設定から

build.gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'

       // 追加
       classpath 'com.uphyca.gradle:gradle-android-apt-plugin:0.9.4'
    }
}

appのbuild.gradle

build.gradle
apply plugin: 'com.android.application'
// 追加 ↑の下に入れる事
apply plugin: 'android-apt'

dependencies {  

    //////// 追加 ////////

    // RxAndroid
    compile 'io.reactivex:rxjava:1.1.0'
    compile 'io.reactivex:rxandroid:1.1.0'
    // Dagger
    compile 'com.google.dagger:dagger:2.2'
    apt 'com.google.dagger:dagger-compiler:2.2'
    // Retrofit
    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'
    // OkHttp
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
    // Gson
    compile 'com.google.code.gson:gson:2.6.2'
}

AndroidManifest.xmlにインターネットパーミッションを1行追加

AndroidManifest.xml
<?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" />

</manifest>

今回使う、為替レートを取得するAPIの作成
rxじゃないObservableをimportしないように注意

ExchangeRateApi.java

public interface ExchangeRateApi {
    String URL = "/latest";

    @GET(URL)
    Observable<ExchangeRateResponse> getExchangeRate(@Query("base") String base,
                                                     @Query("symbols") String symbols);
}

AppModuleを作成

AppModule.java
@Module
public class AppModule {

    Application mApplication;

    public AppModule(Application mApplication) {
        this.mApplication = mApplication;
    }

    @Provides
    @Singleton
    Application provideApplication() {
        return mApplication;
    }
}

ApiModuleを作成

ApiModule.java

@Module
public class ApiModule {

    @Provides
    @Singleton
    Gson provideGson() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        return gsonBuilder.create();
    }

    @Provides
    @Singleton
    OkHttpClient provideOkhttpClient() {
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
        return client.build();
    }

    @Provides
    @Singleton
    Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                // ベースのURLの設定
                .baseUrl("http://api.fixer.io")
                .client(okHttpClient)
                .build();
    }

    @Provides
    @Singleton
    public ExchangeRateApi providesExchangeApi(Retrofit retrofit) {
        return retrofit.create(ExchangeRateApi.class);
    }
}

AppComponentを作成

AppComponent.java
@Singleton
@Component(modules = {AppModule.class, ApiModule.class})
public interface AppComponent {
    void inject(MainActivity activity);
}

一旦、実行もしくはrebuildする(DaggerAppComponentが生成される)
Applicationクラスを継承したAppApplicationを作成

Application.java
public class AppApplication extends Application {

    private AppComponent mAppComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        mAppComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .apiModule(new ApiModule())
                .build();
    }

    public AppComponent getAppComponent() {
        return mAppComponent;
    }
}

Applicationクラスを使うので、AndroidManifest.xmlに android:name=".AppApplication" を一行追記

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kojimation.com.daggerretrofitrxandorid">

    <!-- 追加 -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- このタグの中に追加 -->
    <application
        android:name=".AppApplication"
        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から返って来るレスポンスのオブジェクトを作成

ExchangeRateResponse.java

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;
    }
}
CountryCode.java

public class CountryCode {
    private float JPY;

    public float getJPY() {
        return JPY;
    }
}

MainActivityのxmlにTextViewを1つ追加

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: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から実際に使ってみる

MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Inject
    ExchangeRateApi mExchangeRateApi;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((AppApplication) getApplication()).getAppComponent().inject(this);

        mExchangeRateApi.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()));
                    }
                });
    }
}

実行結果

スクリーンショット 2016-11-14 午後4.51.49.png

Githubにサンプルを置いておきます
https://github.com/MuuKojima/DaggerRetrofitRxAndroidSample
MVPの構成を適用したものを追記しておきます
http://qiita.com/MuuKojima/items/8843c9451339a8b68f22

21
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
18