ダウンロード サンプルファイル (44.1 KB)
別スレッドからGUI更新を行うサンプル
では、別スレッドからGUI更新を行うサンプルアプリケーションを紹介しましょう。
ProgressDialog
時間のかかる処理を行う際に、画面上に進捗状況を表示したい場合があります。そのようなときに便利に使えるAndroidのGUIコンポーネントが、ProgressDialogです。
今回のサンプルは、このProgressDialogクラスをつかったアプリケーションで、実行すると、次のような画面になります。
経過秒数を表示して、5秒後にダイアログが消去される、というものです。経過秒数を表示する処理のところが、メインのスレッドとは別のスレッドになっています。
ProgressDialogの表示
サンプル全体のコードは、次のようになります。
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)の経過秒数を更新するメソッドを少し変更します。
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をとりあげることにします。
参考資料
- 『Javaポケットリファレンス』 WINGSプロジェクト 高江賢 著、山田祥寛 監修、技術評論社、2011年3月
- Java Platform, Standard Edition 6 API 仕様
- Android Developers
この記事は参考になりましたか?
既に会員の方はを行ってください。
- Android開発のためのJava SE再入門連載記事一覧
-
- Androidにおける日付処理の基本
- ストリームでの入出力処理の基本
- コレクションとAndroid非同期処理の基本
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、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本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト 高江 賢(タカエ ケン)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア


