Android Studioでアプリ開発!

Androidアプリ開発初心者の備忘録です。

Android Studioで処理中を表すプログレスダイアログを表示する

処理中を表すプログレスダイアログを表示したい

Androidアプリを開発していると、時間がかかる処理を実装することがあります。【実装編】Android Studioで plist(プロパティリスト) を読み込む - Android Studioでアプリ開発!では、plist ファイルの内容が増えれば増えるほど時間がかかります。このままだとアプリが止まってしまったように思われ、ユーザに対して親切ではありません。今回はそれを改善するために、処理中であることを表すプログレスダイアログを表示する方法について紹介したいと思います。

完成イメージ

plist ファイルのパースが終了するまで処理中を表すプログレスダイアログを表示します。
f:id:jolene:20140725115425p:plain

実装コード

全体のソースです。処理に時間がかかる plist のパース部分を別スレッドにして実行しています。詳細は以下で説明します。

package com.example.plisttest;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

import com.longevitysoft.android.xml.plist.PListXMLHandler;
import com.longevitysoft.android.xml.plist.PListXMLParser;
import com.longevitysoft.android.xml.plist.domain.*;
import com.longevitysoft.android.xml.plist.domain.String;

import java.io.IOException;

import android.os.Handler;
import android.os.Message;

public class MyActivity extends Activity implements Runnable{
    private ProgressDialog progressDialog;
    Thread thread;
    PList pList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        // プログレスダイアログを表示する
        progressDialog = new ProgressDialog(this);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Loading...");
        progressDialog.show();

        // スレッドを開始する
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.my, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void run() {
        PListXMLHandler handler = new PListXMLHandler();
        PListXMLParser parser = new PListXMLParser();
        parser.setHandler(handler);

        try {
            // assets フォルダの plist ファイルを開き、パースする
            parser.parse(this.getAssets().open("english.plist"));
        } catch (IllegalStateException e) {
            // エラー処理を実装する
        } catch (IOException e) {
            // エラー処理を実装する
        }
        pList = ((PListXMLHandler) parser.getHandler()).getPlist();

        // プログレスダイアログを閉じ、Handler に処理を引き継ぐ
        progressDialog.dismiss();
        this.handler.sendEmptyMessage(0);
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message message) {
            java.lang.String text = "";     // TextView に表示するための文字列
            java.lang.String key = "";      // plist からデータを取得するためのキー

            Array array = (Array) pList.getRootElement();

            key = "りんご";
            Dict dict = (Dict) array.get(0);
            String string = dict.getConfiguration(key);
            text = java.lang.String.format("%s=%s\n", key, string.getValue());

            key = "バナナ";
            dict = (Dict) array.get(1);
            string = dict.getConfiguration(key);
            text += java.lang.String.format("%s=%s\n", key, string.getValue());

            key = "みかん";
            dict = (Dict) array.get(2);
            string = dict.getConfiguration(key);
            text += java.lang.String.format("%s=%s\n", key, string.getValue());

            // 画面の TextView に文字列を設定する
            TextView textView = (TextView) findViewById(R.id.textView);
            textView.setText(text);
        }
    };
}

プログレスダイアログを表示し、スレッドを開始する

onCreate() メソッドでプログレスダイアログを表示し、スレッドを開始しています。

時間のかかる処理を run() メソッドに記述する

アクティビティに Runnable インターフェースを実装し、run() メソッドをオーバーライドしています。この部分に時間のかかる処理を記述します。
onCreate() でスレッドを開始すると、run() メソッドが呼ばれます。処理が終了したらプログレスダイアログを閉じ、Handler に処理を引き継ぎます。
run() メソッド内で画面の表示を操作する処理を実行すると例外が発生します。そのため、画面表示に関わる部分は Handler に記述します。

plist の内容を表示する

Handler で、パースされた plist の内容を画面に表示しています。

まとめ

プログレスダイアログを利用することで、時間のかかる plist のパースを処理中として表示することができました。実装にはスレッドを用いました。画面表示に関しては例外が発生しないように注意する必要がありました。
処理中を表すプログレスダイアログは使用する頻度が高めだと思うので、ぜひマスターしてアプリに組み込みたいところです。

Android StudioではじめるAndroidプログラミング入門

Android StudioではじめるAndroidプログラミング入門

初歩からわかるAndroid最新プログラミング 増補改訂版

初歩からわかるAndroid最新プログラミング 増補改訂版