RXJava2 + RetroFit2で WebAPIを叩く

## 仕様

ボタンを押す → WebAPIを非同期で叩く → 結果を TextViewに反映する

livedoor weatherのAPIを使ってみる。 → http://weather.livedoor.com/weather_hacks/

    http://weather.livedoor.com/forecast/webservice/json/v1?city=200010

みたいにcityに都市コードを指定すると、その都市の天気予報が JSON形式で返ってくる。

## manifest

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

## アプリケーションの build.gradle

```build.gradle
dependencies {
    ...
    compile "io.reactivex.rxjava2:rxjava:2.1.11"
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    compile 'com.squareup.retrofit2:retrofit:2.4.0'
    compile 'com.squareup.retrofit2:converter-gson:2.4.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
}
```

## IWeatherAPI.java
````IWeatherAPI.java
public interface IWeatherApi {
    @GET("/forecast/webservice/json/v1")
    Single<WeatherResponse> getWhether(@Query("city") String cityId);

}
```

## WeatherResponse.java
ブラウザで JSONの返り値を見ながら頑張って書く。一番面倒くさいところ。

``` WeatherResponse.java
public class WeatherResponse {
    List<PinPointLocation> pinPointLocations;
    String link;
    List<Forecast> forecasts;
    Location location;
    String publicTime;
    Copyright copyright;
    String title;
    Description description;

    static class PinPointLocation {
        String link;
        String name;
    }

    static class Forecast {
        String dateLavel;
        String telop;
        Temperature temperature;
        Image image;
    }

    static class Temperature {
        TemperatureSub min;
        TemperatureSub max;

        static class TemperatureSub {
            String celsius;
            String fahrenheit;
        }
    }

    static class Image {
        int width;
        String url;
        String title;
        int height;
    }

    static class Location {
        String city;
        String area;
        String prefecture;
    }

    static class Copyright {
        List<Provider> provider;
        String link;
        String title;
        Image image;

        static class Provider {
            String link;
            String name;
        }
    }

    static class Description {
        String text;
        String publicTime;
    }
}
```

## MainActivity : APIアクセスの宣言

``` MainActivity.java
public class MainActivity extends AppCompatActivity {
...
    private IWeatherApi weatherApi;
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://weather.livedoor.com")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        weatherApi = retrofit.create(IWeatherApi.class);

    }
```

## MainActivity: ボタンクリック時の処理
APIの非同期呼び出しと返り値の処理。RxJavaの事をまだ良くわかっていなくて、こういうAPI処理いっこの呼び出しも compositeDisposableに入れてアクティビティ破棄時に処理すべきなのかどうかは不明。

``` MainActivity.java
    private void onButtonClicked() {
        Disposable d = weatherApi.getWhether("200010")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        (response) -> {
                            mTextView_Telop.setText(response.forecasts.get(0).telop);
                            mEditText_Desc.setText(response.description.text);
                        },
                        (err) -> {
                            Log.d(TAG, err.toString());
                            Toast.makeText(MainActivity.this, err.toString(), Toast.LENGTH_SHORT).show();
                        });

        compositeDisposable.add(d);
    }
```