スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android Handlerを利用したスレッド処理

Handlerを利用したスレッド処理

 Android上で重い処理や時間のかかる処理を実行していると、画面がフリーズしてしまい操作できない
状態になることがあります。

この場合、新しいThreadを生成し、そのThreadに重い処理を任せるのが普通だと思いますが、
Androidでは一つだけ問題があります。それは新しいThreadからはウィジェット(GUI)の操作ができないということです。

Androidでのウィジェットの操作は、メインThreadからのみアクセス可能なため、別のThreadからアクセスすると
エラーが発生します。
そのため、別のThreadで重い処理の終わりに画面にメッセージを出力するということができません。

 そこで、別のThreadからウィジェットの操作を可能にするのが「Handler」となります。
あらかじめHanlderにCallbackメソッドを設定します。別ThreadからHandlerに対してアクションすることで、
HandlerのCallbackメソッドを呼び出し、そのCallbackメソッド内でウィジェットに対する処理を行うことができます。


■実行結果


■Handlerを利用したウィジェットの操作サンプル
サンプルでは、別のThreadからHandlerのCallbackメソッドを呼び出し、TextViewへメッセージの出力を行います。

・画面レイアウト
 今回は、Threadを起動するButtonオブジェクトと、処理終了後にメッセージを出力するTextViewオブジェクトを配置します
○main.xml

<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"     
android:layout_width="fill_parent"
     android:layout_height="fill_parent"     >
<Button  android:id="@+id/btn"     
android:layout_width="fill_parent"
    android:layout_height="wrap_content"     
android:text="Button"     />
<TextView  android:id="@+id/txt"     
android:layout_width="fill_parent"
    android:layout_height="wrap_content"     />
</LinearLayout>


・Activityクラス
 今回は、別Threadで処理を実行している際に、ユーザにわかりやすいようにProgressダイアログを表示し、処理中であることをユーザに見せます。
ButtonオブジェクトにThreadの起動を行うonClickListenerを設定し、処理終了後にHandlerのCallbackメソッドを呼び出し、TextViewへメッセージを出力しています。
○HandlerTestアクティビティ

package handler.test;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class HandlerTest extends Activity {
ProgressDialog prg = null;
Handler myHandler = null;
TextView tv = null;

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

       //スレッド実行中に表示するプログレスダイアログ
       prg = new ProgressDialog(this);        
prg.setMessage("loading・・・");①

       //クリックイベントの設定
       ((Button) findViewById(R.id.btn)).setOnClickListener(btnclick);        
   //結果を表示するTextViewを取得
       tv = ((TextView) findViewById(R.id.txt));    
}

    //Buttonのクリックイベント
    OnClickListener btnclick = new OnClickListener() {
@Override
public void onClick(View v) {

prg.show();②

//Handlerの生成
myHandler = new Handler(event);③

//スレッド生成・実行
Thread th = new Thread(run);④
th.start();
}    
};

     //別スレッドで実行する処理内容
Runnable run = new Runnable() {
Override
public void run() {
try {
Thread.sleep(1000 * 3); //3秒 ⑤

//HandlerのCallbackを呼び出す
Message msg = new Message();⑥
msg.obj = "3秒たったお";
myHandler.sendMessage(msg);
} catch (Exception ex) {}
}
};

//Handlerから呼び出されるイベント
    Handler.Callback event = new Handler.Callback() {⑦
@Override
public boolean handleMessage(Message msg) {⑧
tv.setText(msg.obj.toString());
prg.dismiss();
return false;
}
};
}

①Thread処理中に表示するProgressダイアログの生成です。
  ここではメッセージのみ設定します。
②Clickイベントで、まずは処理中メッセージを表示します。
③別スレッドから呼び出すためのHandlerオブジェクトを生成します。
 引数には呼び出すCallbackイベントを設定します。
 ここで設定したCallbackイベントのOverrideしたhandleMessageメソッドが、HanlderのsendMessageなどで呼び出されます。
④Threadを生成します。引数には実行するRunnableを指定します。
⑤今回はシンプルに3秒停止のみとします。
⑥別スレッド内からウィジェットに対して操作するために、HanderのsendMessageをCallします。
 sendMessageは引数にMessage()オブジェクトの指定が可能です。
 HandlerのsendMessageが実行されることによって、Handler生成時に指定したCallbackイベントが実行されます。
 実際はCallbackイベントにOverrideしたhandleMessage()メソッドが実行されます。
⑦HandlerのCallbackイベントです。
⑧実際にCallbackから呼び出されるhandleMessage()メソッドをOverrideします。
 引数には、HandlerのsendMessageメソッドの呼び出し時に設定したMessageオブジェクトが格納されます。引数のMessageオブジェクトからのメッセージをTextViewへ表示し、Thread開始時に表示したProgressダイアログを閉じます(dismiss)。

■まとめ
 なんにでも当てはまるがユーザビリティを向上させるには、マルチスレッド化が重要。
Handlerを有効活用することで、ユーザに処理を意識させずに重い処理を行うことが可能となる。
Threadによる処理、Handlerによるウィジェットの操作を的確に使いこなせるようになることが大切。

■おまけ
 HandlerのCallbackとRunnableをクラスで実装したパターン

package handler.test;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class HandlerTest2  extends Activity implements Callback, Runnable {
ProgressDialog prg = null;
Handler myHandler = null;
Thread myThread = null;
TextView tv = null;

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

         //スレッド実行中に表示するプログレスダイアログ
        prg = new ProgressDialog(this);        
prg.setMessage("loading・・・");

        //クリックイベントの設定
        ((Button) findViewById(R.id.btn)).setOnClickListener(btnclick);        
//結果を表示するTextViewを取得
        tv = ((TextView) findViewById(R.id.txt));

//Handlerの生成
myHandler = new Handler(this);
//スレッド生成・実行
myThread = new Thread(this);    
}     //Buttonのクリックイベント
OnClickListener btnclick = new OnClickListener() {
@Override
public void onClick(View v) {
prg.show();
myThread.start();
}    
};
@Override
public void run() {
try {
Thread.sleep(3000);

//HandlerのCallbackを呼び出す
Message msg = new Message();
msg.obj = "3秒たったお";
myHandler.sendMessage(msg);
} catch (Exception ex) {}
}

@Override
public boolean handleMessage(Message msg) {
tv.setText(msg.obj.toString());
prg.dismiss();
return false;
}

}
スポンサーサイト

テーマ : android
ジャンル : コンピュータ

コメントの投稿

非公開コメント

おすすめアプリ
カテゴリ
最新記事
リンク
アクセスカウンター
アクセス解析
imobile
i-mobile
i-mobile
i-mobile
i-mobile
i-mobile
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
Amazon
Androidお勧め参考書
EC studio
商品
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。