SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Android Studio 2で始めるアプリ開発入門

Androidアプリでの非同期処理とWeb API連携

Android Studio 2で始めるアプリ開発入門 第11回


  • X ポスト
  • このエントリーをはてなブックマークに追加

JSONデータの表示

 ここまでで、一度アプリを再起動し、都市リスト画面をタップしてみてください。お天気詳細画面が表示されますが、特に何も変化がありません。画面上変化がありませんが、確実に裏でhttpアクセスを行い、お天気JSONデータを取得してきています。しかし、せっかく取得したJSONデータを表示する処理が記述されていないので、このような結果になっています。そこで、次に、その部分を記述していきます。

UIスレッドとバックグラウンド

 この処理はonPostExecute()メソッドに記述しますが、なぜ、doInBackground()ではだめなのでしょうか。それは、doInBackground()とonPostExecute()とでは実行しているスレッドが違うからなのです。doInBackground()は名前の通りバックグラウンドスレッドで実行し、onPostExecute()はUIスレッドで実行されます。そして、画面への表示などの処理はUIスレッドで実行されるメソッドに記述する必要があるのです。

 onPostExecute()に限らず、AsyncTaskクラスのAPIリファレンスページを参照すると、さまざまなメソッドが用意されていますが、それぞれ実行するタイミングとスレッドを理解しておく必要があります。これらを図にすると以下のようになります。

図6 AsyncTaskの各メソッドの実行タイミング
図6 AsyncTaskの各メソッドの実行タイミング
  • onPreExecute():doInBackground()の前にUIスレッド上で実行される
  • onPostExecute():doInBackground()の後にUIスレッド上で実行される
  • onProgressUpdate():doInBackground()中にpublishProgress()メソッドを呼び出したタイミングにてUIスレッド上で実行される

コンストラクタの追加

 では、onPostExecute()へソースコードを記述していきますが、その際、お天気情報を表示する画面部品をあらかじめWeatherInfoReceiverが取得しておく必要があります。これは、コンストラクタで受け取り、フィールドに格納することにします。以下のソースコードをWeatherInfoReceiverに追記してください。

リスト5 WeatherInfoReceiverにフィールドとコンストラクタを追加
private class WeatherInfoReceiver extends AsyncTask<String, String, String> {
    private String _cityName;
    private TextView _tvCityName;
    private TextView _tvWeatherTelop;
    private TextView _tvWeatherDesc;
    public WeatherInfoReceiver(String cityName, TextView tvCityName, TextView tvWeatherTelop, TextView tvWeatherDesc) {
        _cityName = cityName;
        _tvCityName = tvCityName;
        _tvWeatherTelop = tvWeatherTelop;
        _tvWeatherDesc = tvWeatherDesc;
    }
        ~省略~
}

 コンストラクタを追記したため、このクラスをnewしているところを以下のように変更します。

リスト6 onCreate()メソッドのソースコードを変更
protected void onCreate(Bundle savedInstanceState) {
        ~省略~
    TextView tvCityName = (TextView) findViewById(R.id.tvCityName);
    TextView tvWeatherTelop = (TextView) findViewById(R.id.tvWeatherTelop);
    TextView tvWeatherDesc = (TextView) findViewById(R.id.tvWeatherDesc);

    WeatherInfoReceiver receiver = new WeatherInfoReceiver(cityName, tvCityName, tvWeatherTelop, tvWeatherDesc);
    receiver.execute(cityId);
}

onPostExecuteへの追記

 では、準備が整いましたので、onPostExecute()へ以下のソースコードを記述します。

リスト7 onCreate()メソッドのソースコードを変更
public void onPostExecute(String result) {
    String desc = "";
    String dateLabel = "";
    String telop = "";
    try {
        JSONObject rootJSON = new JSONObject(result);  // (1)
        JSONObject descriptionJSON = rootJSON.getJSONObject("description");  // (2)
        desc = descriptionJSON.getString("text");  // (3)
        JSONArray forecasts = rootJSON.getJSONArray("forecasts");  // (4)
        JSONObject forecastNow = forecasts.getJSONObject(0);
        dateLabel = forecastNow.getString("dateLabel");  // (3)
        telop = forecastNow.getString("telop");  // (3)
    }
    catch(JSONException ex) {
    }
    _tvCityName.setText(_cityName + "の" + dateLabel + "の天気: ");  // (5)
    _tvWeatherTelop.setText(telop);  // (5)
    _tvWeatherDesc.setText(desc);  // (5)
}

 ここで注意するのは、onPostExecute()の引数です。この引数resultはdoInBackground()の戻り値です。ここでは、httpアクセスで取得してきたお天気情報JSON文字列です。このJSON文字列をJSONの仕様に従って解析すればそれぞれのお天気情報が取得できます。

 リスト7のtryブロック内の処理がそれに当たります。ここでは、JSONObjectクラスを使用してJSONデータを取得しています。JSONObjectは、new時に引数でJSON文字列を渡します(リスト7の(1))。その後、JSONObjectの各種メソッドを利用して、入れ子になっているJSONオブジェクトを取得したり(リスト7の(2))、JSON配列を取得したりできます(リスト7の(4))。最終的には、getString()メソッドで名前を指定することで、JSONオブジェクト直下の文字列を取得します(リスト7の(3))。

 JSONから取り出したお天気情報をコンストラクタでフィールドに格納した画面部品にそれぞれ表示すれば出来上がりです(リスト7の(5))。

 この状態でアプリを再起動してください。無事、お天気情報が表示されるはずです。

まとめ

 今回は、Web API連携とその時に必須の考え方である非同期処理を解説しました。次回は音声ファイルといったメディア再生を扱います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Android Studio 2で始めるアプリ開発入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook<個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9746 2018/05/23 15:37

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング