SHOEISHA iD

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

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

Android開発のためのJava SE再入門

コレクションとAndroid非同期処理の基本

Android開発のためのJava SE再入門(5)

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

別スレッドからGUI更新を行うサンプル

 では、別スレッドからGUI更新を行うサンプルアプリケーションを紹介しましょう。

ProgressDialog

 時間のかかる処理を行う際に、画面上に進捗状況を表示したい場合があります。そのようなときに便利に使えるAndroidのGUIコンポーネントが、ProgressDialogです。

 今回のサンプルは、このProgressDialogクラスをつかったアプリケーションで、実行すると、次のような画面になります。

サンプルの実行イメージ
サンプルの実行イメージ

 経過秒数を表示して、5秒後にダイアログが消去される、というものです。経過秒数を表示する処理のところが、メインのスレッドとは別のスレッドになっています。

ProgressDialogの表示

 サンプル全体のコードは、次のようになります。

リスト1 HelloAndroidクラス
public class HelloAndroid extends Activity {

    ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // ProgressDialogのインスタンスを生成する
        progressDialog = new ProgressDialog(this);

        // ProgressDialogのスタイルを設定する
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

        // メッセージを設定する
        progressDialog.setMessage("処理を実行中です...");

        // 表示
        progressDialog.show();

        // 経過秒数を表示するスレッド(1)
        new Thread(new Runnable() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    updateProgress(i);
                }
               // ダイアログの消去
               progressDialog.dismiss();
            }
        }).start();
    }

    // 経過秒数を更新する(2)
    public void updateProgress(final int val)  {
        try {
            // 1秒待機
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        // 経過秒数更新
        progressDialog.setMessage( val + "秒経過");
    }
}

 まずProgressDialogの使い方を説明しましょう。特に難しいものではありません。インスタンス化した後は、各種設定を行います。setProgressStyleメソッドは、表示スタイルの設定です。ここでは定数STYLE_SPINNERを指定していますが、STYLE_HORIZONTALを指定すれば、進捗率をバーで表示するタイプになります。

 setMessageメソッドは、ダイアログに表示するメッセージの設定で、showメソッドは、ダイアログを表示します。ダイアログを消去するには、dismissメソッドを実行します。

 (1)の経過秒数を表示するスレッドでは、forループで、経過秒数の更新処理(updateProgressメソッド)をくりかえし呼び出し、その後、ProgressDialogを消去しています。

 (2)の経過秒数を更新する箇所では、1秒待機後、setMessageメソッドで文字を更新しています。なお、通常のアプリケーションであれば、1秒待機する部分で、時間のかかる処理を行うことになるでしょう。

Handlerクラスを使う

 このサンプルには問題がないように見えますが、じつはこれを実行すると、次のような表示となり例外が発生してしまいます。

例外が発生する
例外が発生する

 これは、別スレッド(経過秒数を表示するスレッド)の中から直接GUIの更新(setMessageメソッドの実行)を行ったからなのです。

 そこで、Handlerクラスを使って、GUI更新のメッセージをメッセージキューに投入するようにします。以下のように、Handler変数の追加と、(2)の経過秒数を更新するメソッドを少し変更します。

リスト2 HelloAndroidクラスの一部
public class HelloAndroid extends Activity {

    Handler handler = new Handler();

    ~ 中略 ~

    // 経過秒数を更新する(2)
    public void updateProgress(final int val) {

        // 1秒待機
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        handler.post(new Runnable() {
            public void run() {
                // 経過秒数更新
                progressDialog.setMessage(val + "秒経過");
            }
        });
    }
}

 まずHandlerクラスをインスタンス化して、メインスレッドのLooperオブジェクトに関連づけます。そして、postメソッドでメッセージをメッセージキューに投入しています。postメソッドの引数は、Runnableオブジェクトになっています。つまり、メッセージとしてRunnableオブジェクトを指定できるということです。ここでは、runメソッドに、progressDialog.setMessageの呼び出しをそのまま記述したオブジェクトを指定しています。

 こうすることで、GUIスレッドがメッセージをとりだし、progressDialogのsetMessageメソッドを実行する、という処理になるわけです。

最後に

 今回は、ジェネリクス、コレクションと、Androidの非同期処理の基本を説明しました。次回はストリーム関連のAPIをとりあげることにします。

参考資料

  1. Javaポケットリファレンス』 WINGSプロジェクト 高江賢 著、山田祥寛 監修、技術評論社、2011年3月
  2. Java Platform, Standard Edition 6 API 仕様
  3. Android Developers

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
Android開発のためのJava SE再入門連載記事一覧

もっと読む

この記事の著者

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

静岡県榛原町生まれ。一橋大学経済学部卒業後、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編 」他、著書多数

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

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6135 2011/09/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング