AndroidでUIを更新するスレッド:Thread、Handler、Looper、TimerTaskなど


方法1:(java習慣、androidでは推奨されません)
androidスレッドのプログラミングを始めたばかりの頃、javaのように慣れて、次のコードで問題を解決しようとしました.

  
new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start();

機能を実装し、UIインタフェースをリフレッシュすることができます.しかし、これは単一スレッドモデルに反するためです.Android UI操作はスレッドが安全ではなく、UIスレッドで実行する必要があります.
 
方法2:(Thread+Handler)
ドキュメントとapidemoを調べたところ,Handlerを用いてUIスレッドの更新を実現する方法が一般的であることが分かった.
Handlerは、受信したメッセージに基づいてUI更新を処理する.Threadスレッドは、Handlerメッセージを発行し、UIの更新を通知する.

  
Handler myHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case TestHandler.GUIUPDATEIDENTIFIER: myBounceView.invalidate(); break ; } super .handleMessage(msg); } };

  
class myThread implements Runnable { public void run() { while ( ! Thread.currentThread().isInterrupted()) { Message message = new Message(); message.what = TestHandler.GUIUPDATEIDENTIFIER; TestHandler. this .myHandler.sendMessage(message); try { Thread.sleep( 100 ); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } }

以上の方法demo見:http://rayleung.javaeye.com/blog/411860
方法3:(java習慣、お勧めしません)
Androidプラットフォームでは、Javaに付属しているTimerTaskクラスを周期的に実行する方法を繰り返す必要があります.TimerTaskはThreadに比べてリソース消費が低く、Androidに付属しているAlarmManagerを使用してTimerタイマを使用する以外に、より良い解決方法です.import java.util.Timer、import java.util.TimerTaskを導入する必要があります.

  
public class JavaTimer extends Activity { Timer timer = new Timer(); TimerTask task = new TimerTask(){ public void run() { setTitle( " hear me? " ); } }; public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); timer.schedule(task, 10000 ); } }

方法四:(TimerTask+Handler)
実際にはそれはできませんが、Androidのスレッドセキュリティと関係があります!Handlerに合わせることでtimer機能を実現すべきです!

  
public class TestTimer extends Activity { Timer timer = new Timer(); Handler handler = new Handler(){ public void handleMessage(Message msg) { switch (msg.what) { case 1 : setTitle( " hear me? " ); break ; } super .handleMessage(msg); } };  
TimerTask task = new TimerTask(){ public void run() { Message message = new Message(); message.what = 1 ; handler.sendMessage(message); } };  
public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main);  
timer.schedule(task, 10000 ); } }

方法5:(Runnable+Handler.postDelayed(runnable,time) )
AndroidではUIを定期的に更新し、通常は java.util.Timer, JAva.util.TimerTask,android.os.Handlerの組み合わせ.実際にはHandler自体がタイミング機能を提供している. 

  
private Handler handler = new Handler(); private Runnable myRunnable = new Runnable() { public void run() { if (run) { handler.postDelayed( this , 1000 ); count ++ ; } tvCounter.setText( " Count: " + count); } };

そして他の場所で呼び出す
handler.post(myRunnable);
handler.post(myRunnable,time);
ケース:http://shaobin0604.javaeye.com/blog/515820
====================================================================
知識ポイントのまとめ:
   AndroidやJavaで開発された初心者の多くは、Thread、Looper、Handler、Messageに迷っており、HandlerThread、java.util.concurrent、Task、AsyncTaskが現在市販されている書籍などの資料でこれらの問題に言及していないため、今日はこの問題についてより系統的にまとめています.私たちが作成したサービス、Activity、Broadcastはいずれもメインですスレッド処理は、ここではUIスレッドとして理解することができますが、I/O読み書きの大きなファイル読み書き、データベース操作、ネットワークダウンロードなど、時間のかかる操作を行う場合、ユーザーインタフェースをブロックしないためにANRの応答プロンプトウィンドウが表示されます.この場合、Threadスレッドを使用して解決することも考えられます.
   J 2 MEの開発に携わったプログラマーにとってThreadは比較的簡単で、直接匿名でrunメソッドを書き換え、startメソッドを呼び出して実行すればよい.あるいはRunnableインタフェースから継承されるが、AndroidプラットフォームにとってUIコントロールはスレッドセキュリティタイプに設計されていないため、いくつかの同期メカニズムを導入してリフレッシュする必要がある.GoogleはAndroidを設計する際に下Wを参考にしたin 32のメッセージ処理メカニズム.
 1.スレッド内のビューをベースクラスとしてリフレッシュするインタフェースについては、postInvalidate()メソッドを使用してスレッド内で処理することができ、postInvalidate(int left,int top,int right,int bottom)などの書き換えメソッドを使用して矩形領域をリフレッシュしたり、postInvalidateDelayMilliseconds(long delayMilliseconds)やpostInvalidateDelayDelayDelayDelayMilliseconds(postInvalidateDelayed)などの遅延実行を行ったりすることもできます.(long delayMilliseconds,int left,int top,int right,int bottom)メソッドで、最初のパラメータはミリ秒です.
 2.もちろん推奨される方法はHandlerによって処理され、1つのスレッドのrunメソッドでhandlerオブジェクトを呼び出すpostMessageまたはsendMessageメソッドで実現されます.Androidプログラムの内部にはメッセージキューが維持されており、これらを順番に処理します.Win 32プログラマーであればこれらのメッセージ処理をよく理解できますが、Androidに比べてPreTは提供されていません.ranslateMessageこれらの干渉内部の方法.
3.Looperとは何でしょうか.実はAndroidの各ThreadにはLooperが付いています.LooperはThreadがメッセージキューを維持するのに役立ちますが、LooperとHandlerには何の関係もありません.オープンソースのコードからAndroidがThread継承クラスHanderThreadを提供していることがわかります.HandlerThreadオブジェクトではgetLooperメソッドで入手できます.Looperオブジェクトハンドルを取ると、このLooperオブジェクトをHandlerにマッピングしてスレッド同期メカニズムを実現することができます.Looperオブジェクトの実行にはLooper.prepareメソッドを初期化する必要があります.昨日見た問題です.同時に、リソースを解放し、Looper.releaseメソッドを使用します.
4.Message Androidとは何ですか.AndroidではHandlerがいくつかのコンテンツを渡すことができ、BundleオブジェクトでString、Integer、Blobバイナリオブジェクトをカプセル化することができます.HandlerオブジェクトのsendEmptyMessageまたはsendMessageメソッドをスレッドで使用することでBundleオブジェクトをHandlerプロセッサに渡すことができます.Handlerクラスでは書き換え方法handleMessageが提供されています(Message msg) 判断として、msg.whatにより各情報を区別する.Bundleをパケット化してHandlerクラス更新UIスレッドにおけるコンテンツ実装制御のリフレッシュ動作を実現する.関連するHandlerオブジェクトに関するメッセージ送信sendXXXXに関する方法は以下の通りである.またpostXXXXに関する方法もあるが、これらはWin 32の理屈とほぼ一致しており、1つは送信後に直接戻り、1つは処理後に戻る.
5.java.util.concurrentオブジェクト分析過去にJava開発に携わったプログラマーはConcurrentオブジェクトに慣れていないでしょう.JDK 1.5以降に追加された重要な特性をハンドヘルドデバイスとして使用することを提唱していません.Androidが私たちのために設計したTaskメカニズムを考慮して、ここではあまり説明しません.関連原因は以下の紹介を参照してください.
6.Androidでは、TaskおよびAsyncTaskというスレッドとは異なる処理方法も提供されており、オープンソースコードからConcurrent向けのパッケージが見られ、開発者はこれらの非同期タスクを容易に処理することができる.