2012年7月25日水曜日

androidでマルチスレッド(バックグランド処理)

Androidでは、マルチスレッド化の方法として、以下のいづれかを選択することができます。

  1. Java標準Threadクラスを使う
  2. Androidで提供されているAsyncTaskを使う

その1では、1番のJava標準Threadクラスを使った例を説明します。
まず、Activity起動直後にプログレスダイアログを表示し、バックグランド処理用のThreadを起動するコードを見てみましょう。

(動作しない不完全コード例)

1 package com.team_hiroq.sample;
2  
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.view.View;
6 import android.view.View.OnClickListener;
7 import android.widget.TextView;
8  
9 public class ThreadSample1 extends Activity implements OnClickListener{
10     TextView mTextView;
11  
12     @Override
13     public void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.theadsample1);
16          
17         //TextView取得
18         mTextView = (TextView)findViewById(R.id.ThreadSample1);
19         //TextViewタップ時にonClick実行
20         findViewById(R.id.ThreadSample1).setOnClickListener(this);
21     }
22  
23     @Override
24     public void onClick(View arg0) {
25         // スレッド起動
26         (new Thread(new Runnable() {
27             @Override
28             public void run() {
29                 // 通常バックグランドをここに記述します
30                 .....
31                  
32                 //取得したイメージをImageViewに設定
33                 mTextView.setText("Thread Samples");
34             }
35         })).start();
36     }
37 }

これを実行するとすぐわかりますが、mImage.setBackgroundDrawableを実行したタイミングで例外が発生します。これは、Androidでは、UIに関する処理は、UIのThreadからしか処理できない仕組みになっているためです。
上記の例で言えば、ImageViewが属するUIスレッドとsetBackgroundDrawableを実行しようとしているスレッドが異なるため例外が発生しています。

この問題を解決をするための機構として、AndroidではHandlerクラスが提供されており、別スレッドからUIの処理を行いたい場合、Handler経由でUIの処理を実行します。
使い方は以下の2ステップです

  1. HandlerクラスのインスタンスをUIスレッドで作成
  2. Handler.postにRunableを渡して、Runable.runの中でUI関連の処理を実行
1 package com.team_hiroq.sample;
2  
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.os.Handler;
6 import android.view.View;
7 import android.view.View.OnClickListener;
8 import android.widget.TextView;
9  
10 public class ThreadSample1 extends Activity implements OnClickListener{
11     Handler  mHandler   = new Handler();        //Handlerのインスタンス生成
12     TextView mTextView;
13  
14     @Override
15     public void onCreate(Bundle savedInstanceState) {
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.theadsample1);
18          
19         //TextView取得
20         mTextView = (TextView)findViewById(R.id.ThreadSample1);
21         //TextViewタップ時にonClick実行
22         findViewById(R.id.ThreadSample1).setOnClickListener(this);
23     }
24  
25     @Override
26     public void onClick(View arg0) {
27         // スレッド起動
28         (new Thread(new Runnable() {
29             @Override
30             public void run() {
31                 // 通常バックグランドをここに記述します
32                 .....
33                  
34                 /**
35                  * Handlerのpostメソッドを使ってUIスレッドに処理をdispatchします
36                 */
37                 mHandler.post(new Runnable() {
38                     @Override
39                     public void run() {
40                         //取得したイメージをImageViewに設定
41                         mTextView.setText("Thread Samples");
42                     }
43                 });
44             }
45         })).start();
46     }
47 }

0 件のコメント:

コメントを投稿