androidのhandler
16661 ワード
もうすぐ1年间ブログを更新していないで、この1年は少し奔走することに疲れて、详しくQ空间の中で更に书くようにしましょう.Androidに転身したので、新しい学习の过程を始めました.今回のブログの新たな成长を期待しています.
この文書はHandlerについてです.Handlerは主にサブスレッドから送信されたデータを受け取り,このデータをメインスレッドに合わせてUIを更新する.アプリケーションが起動すると、Androidはまずメインスレッド(つまりUIスレッド)を開きます.メインスレッドは管理インタフェースのUIコントロールであり、イベントの配布を行います.例えば、Buttonをクリックすると、AndroidはButtonにイベントを配布し、操作に応答します.この時点で時間のかかる操作が必要な場合、例えば、ネットワークでデータを読み取るか、ローカルの大きなファイルを読み取る場合は、これらの操作をメインスレッドに置くことはできません.メインスレッドに置くと、インタフェースに偽死現象が発生し、5秒も完成していない場合は、Androidシステムのエラーメッセージ「強制閉鎖」が表示されます.
この場合、サブスレッドはUIの更新に関連しているため、Androidプライマリスレッドはスレッドが安全ではありません.つまり、UIの更新はプライマリスレッドでしか更新できません.サブスレッドでの操作は危険です.この時、Handlerはこの複雑な問題を解決するために現れた.Handlerは、メインスレッド(UIスレッド)で動作し、サブスレッドとMessageオブジェクトを介してデータを伝達することができる.このとき、Handlerは、サブスレッドからの(サブスレッドはsedMessage()メソッドで伝達される)Messageオブジェクト(データを含む)を受け取り、これらのメッセージをメインスレッドキューに入れ、メインスレッドに合わせてUIを更新する.
Handlerのいくつかの特徴:HandlerはMessageオブジェクトとRunnableオブジェクトをプライマリ・スレッドに配布することができ、各Handlerインスタンスは、作成されたスレッド(一般的にプライマリ・スレッドに存在する)にバインドされ、(1):メッセージのスケジュールまたはRunnableがプライマリ・スレッドのどこかで実行され、(2)アクションが異なるスレッドで実行されるようにスケジュールされます.
Handlerでメッセージを配信するにはpost(Runnable)メソッドとsendMessage(Message)メソッドがよく使用されます.
まずsendMessageの例です.
簡単に言えば、ActivityのonCreateメソッドでスレッドを起動し、このスレッドのrunメソッドでMessageオブジェクトを使用してHandlerのsendMessageメソッドを使用してキューに送信し、最後にActivityでnewのHandlerの内部クラスでhandMessageメソッドを実現し、このメソッドを使用してキュー内のMessageオブジェクトを取り出して非同期操作を実現します.
次にpostの例ですが、ここで少しお話しして、そのままnew Handler()を使います.post(Runnable)のような書き方は,新規にスレッドを開くことはなく,つまり依然としてマスタスレッドで実行され,startメソッドではなくスレッドを単純に呼び出したrunメソッドに相当する.これはandroidのバグだと言われていますが、ソリューションはこのように使用されています.
完全なpostの例を見てみましょう
このdemoではHandlerThreadが用いられ,HandlerThreadオブジェクトでgetLooper法によりLooperオブジェクト制御ハンドルを取得でき,このLooperオブジェクトをHandlerにマッピングしてスレッド同期機構を実現できる.そこで以下の結果が得られた.1:コンソールの出力:Oncreate---The Thread id is:1 Runnable---The Thread is running Runnable---The Thread id is:10 2:プログラムが起動すると、すぐにmainが表示されます.xmlの内容.これによりマルチスレッドの結果が得られる.
この文書はHandlerについてです.Handlerは主にサブスレッドから送信されたデータを受け取り,このデータをメインスレッドに合わせてUIを更新する.アプリケーションが起動すると、Androidはまずメインスレッド(つまりUIスレッド)を開きます.メインスレッドは管理インタフェースのUIコントロールであり、イベントの配布を行います.例えば、Buttonをクリックすると、AndroidはButtonにイベントを配布し、操作に応答します.この時点で時間のかかる操作が必要な場合、例えば、ネットワークでデータを読み取るか、ローカルの大きなファイルを読み取る場合は、これらの操作をメインスレッドに置くことはできません.メインスレッドに置くと、インタフェースに偽死現象が発生し、5秒も完成していない場合は、Androidシステムのエラーメッセージ「強制閉鎖」が表示されます.
この場合、サブスレッドはUIの更新に関連しているため、Androidプライマリスレッドはスレッドが安全ではありません.つまり、UIの更新はプライマリスレッドでしか更新できません.サブスレッドでの操作は危険です.この時、Handlerはこの複雑な問題を解決するために現れた.Handlerは、メインスレッド(UIスレッド)で動作し、サブスレッドとMessageオブジェクトを介してデータを伝達することができる.このとき、Handlerは、サブスレッドからの(サブスレッドはsedMessage()メソッドで伝達される)Messageオブジェクト(データを含む)を受け取り、これらのメッセージをメインスレッドキューに入れ、メインスレッドに合わせてUIを更新する.
Handlerのいくつかの特徴:HandlerはMessageオブジェクトとRunnableオブジェクトをプライマリ・スレッドに配布することができ、各Handlerインスタンスは、作成されたスレッド(一般的にプライマリ・スレッドに存在する)にバインドされ、(1):メッセージのスケジュールまたはRunnableがプライマリ・スレッドのどこかで実行され、(2)アクションが異なるスレッドで実行されるようにスケジュールされます.
Handlerでメッセージを配信するにはpost(Runnable)メソッドとsendMessage(Message)メソッドがよく使用されます.
まずsendMessageの例です.
- public class HandlerActivity extends Activity {
-
- private TextView textView;
-
- private MyHandler myHandler;
-
- private Button button;
-
- private ProgressBar progressBar;
-
- private MyThread m=new MyThread();
-
- /** Called when the activity is first created. */
-
- @Override
-
- public void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.main);
-
- textView=(TextView)findViewById(R.id.text);
-
- button=(Button)findViewById(R.id.startButton);
-
- progressBar=(ProgressBar)findViewById(R.id.bar);
-
- progressBar.setMax(100);
-
- button.setOnClickListener(new View.OnClickListener() {
-
- @Override
-
- public void onClick(View arg0) {
-
- myHandler=new MyHandler();
-
- new Thread(m).start();
-
- System.out.println("onCreate--The Thread is: "+Thread.currentThread().getId());
-
- }
-
- });
-
- }
-
- // UI , UI
-
- class MyHandler extends Handler{// Handler , handleMessage
-
- public MyHandler(){
-
- }
-
- public MyHandler(Looper l){
-
- super(l);
-
- }
-
- @Override
-
- public void handleMessage(Message msg) {// , ,
-
- System.out.println("Handler--The ThreadId is: "+Thread.currentThread().getId());
-
- super.handleMessage(msg);
-
- Bundle b=msg.getData();
-
- String textStr0=textView.getText().toString();
-
- String textStr1=b.getString("textStr");
-
- HandlerActivity.this.textView.setText(textStr0+" "+textStr1);// TextView
-
- int barValue=b.getInt("barValue");HandlerActivity.this.progressBar.setProgress(barValue);//
-
- }
-
- }
-
- //
-
- class MyThread implements Runnable{
-
- int i=1;
-
- @Override
-
- public void run() {
-
- while(i<11){
-
- System.out.println("Thread--The ThreadId is: "+Thread.currentThread().getId());
-
- try {
-
- Thread.sleep(1000);
-
- } catch (InterruptedException e) {
-
- e.printStackTrace();
-
- }
-
- Message msg=new Message();
-
- Bundle b=new Bundle();
-
- b.putString("textStr", " "+i+" ");
-
- b.putInt("barValue", i*10);
-
- i++;
-
- msg.setData(b);
-
- HandlerActivity.this.myHandler.sendMessage(msg);// sendMessage Handler UI
-
- }
-
- }
-
- }
-
- }
簡単に言えば、ActivityのonCreateメソッドでスレッドを起動し、このスレッドのrunメソッドでMessageオブジェクトを使用してHandlerのsendMessageメソッドを使用してキューに送信し、最後にActivityでnewのHandlerの内部クラスでhandMessageメソッドを実現し、このメソッドを使用してキュー内のMessageオブジェクトを取り出して非同期操作を実現します.
次にpostの例ですが、ここで少しお話しして、そのままnew Handler()を使います.post(Runnable)のような書き方は,新規にスレッドを開くことはなく,つまり依然としてマスタスレッドで実行され,startメソッドではなくスレッドを単純に呼び出したrunメソッドに相当する.これはandroidのバグだと言われていますが、ソリューションはこのように使用されています.
- HandlerThread handlerThread = new HandlerThread("myHandlerThread");
- handlerThread.start();
- handler = new Handler(handlerThread.getLooper());
完全なpostの例を見てみましょう
- public class MyThread extends Activity {
- private Handler handler = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- HandlerThread handlerThread = new HandlerThread("myHandlerThread");
- handlerThread.start();
- handler = new Handler(handlerThread.getLooper());
- handler.post(new MyRunnable());
- System.out.println("Oncreate---The Thread id is :"
- + Thread.currentThread().getId());
- setContentView(R.layout.main);
- }
- private class MyRunnable implements Runnable {
- public void run() {
- System.out.println("Runnable---The Thread is running");
- System.out.println("Runnable---The Thread id is :"
- + Thread.currentThread().getId());
- try {
- Thread.sleep(6000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
このdemoではHandlerThreadが用いられ,HandlerThreadオブジェクトでgetLooper法によりLooperオブジェクト制御ハンドルを取得でき,このLooperオブジェクトをHandlerにマッピングしてスレッド同期機構を実現できる.そこで以下の結果が得られた.1:コンソールの出力:Oncreate---The Thread id is:1 Runnable---The Thread is running Runnable---The Thread id is:10 2:プログラムが起動すると、すぐにmainが表示されます.xmlの内容.これによりマルチスレッドの結果が得られる.