Handler非同期メッセージメカニズムのインスタンス解析
8122 ワード
いくつかの簡単な例でHandlerに関する知識点を整理し、後で調べるのに便利で、みんなが早くこの知識点をマスターするのに便利です.
名詞解釈:Messageはスレッド間で伝達されるメッセージであり、内部で少量の情報を携帯し、異なるスレッド間でデータを交換することができる.MessageQueueはメッセージキューで、Handlerによって送信されたすべてのメッセージを格納するために主に使用されます.このメッセージはメッセージキュー内で処理されるのを待っています.Handlerは、主にメッセージの送信および処理に使用される処理者である.送信メッセージは一般にhandlerのsendMessage()を使用し、処理メッセージはhandleMessage()を呼び出す.LooperはスレッドごとにMessageQueueの執事であり,loop()メソッドを呼び出すと無限ループに入り,MessageQueueにメッセージが存在することを発見するたびに取り出しhandleMessage()メソッドに渡す.
注意:各スレッドにはLooperオブジェクトとMessageQueueが1つしかありません.Handlerは作成時に存在するスレッドに依存する.
コード例の原理を使ってみましょう.
ターゲットシーン:メインスレッドはサブスレッドにメッセージを送信し、サブスレッドはメインスレッドのメッセージを受信した後、メインスレッドに通知を送信し、メインスレッドはUIを更新します.
実装手順:1,メインスレッドはサブスレッドにメッセージを送信し,サブスレッドはメッセージを受信する.サブスレッド受信メッセージである以上、handleMessageはサブスレッドにあることを示す.Handlerはサブスレッドに依存する.コードは次のとおりです.
Runnableインタフェースを実装したサブスレッドで、handlerがインスタンス化され、handleMessageを介してメッセージが受信されます.ここにLooperがありますprepare();ロoperとloop();説明は、サブスレッド自体が新しく作成したメッセージ執事looper(メインスレッドにはデフォルトで独自のlooperが作成されています)です.プライマリ・スレッドからメッセージを送信すると、直接呼び出すことができます.mHandler.sendEmptyMessage(1);”(LoopThreadはRunnableインタフェースを実現したクラスである).
次に,サブスレッド受信処理メッセージとメインスレッド処理メッセージの両方がhandleMsgAndTodo(msg)メソッドにカプセル化される.コードは次のとおりです.
ホストからのメッセージmsg.what=1,ここでメッセージを受信するとすぐにメインスレッドにメッセージmsgを送信する.0であることに注意してmHandlerやloopThreadではなくhandlerを使用します.mHandler,ここでhandlerはメインスレッドでインスタンス化されている.コードは次のとおりです.
ここでhandlerはメインスレッドに依存しており,UIを直接更新することができる.また,非同期メッセージメカニズムに基づいたいくつかの方法もある.例えば、サブスレッドでUIを更新する例:
上記のいくつかのコードの方法は、プライマリスレッドのhandlerを呼び出してメッセージ更新UIを送信することにほかならない.サブスレッドでインスタンス化されたもう1つのhandler 2も、メインスレッドのlooper、すなわちメインスレッドと同じメッセージキューを維持することを共用しているため、メインスレッドでUIを更新することに相当する.
自己理解:どのスレッドがメッセージを受信するかは、そのスレッドでhandleMessageを呼び出すためにHandlerをインスタンス化します.メインスレッドがサブスレッドにメッセージを送る場合はLooperを使用する必要がある.prepare()とLooper.loop()は、handleMessage()を呼び出すために、Handlerをサブスレッドにインスタンス化する.
サブスレッドではnew Handler(Looper.getMainLooper()はそのhandleMessage()メソッドのことがメインUIスレッドで処理されていることを示し,このHandlerは実はメインスレッドにバインドされている.hander.post(),view.post()、runOnUI Thread()のいくつかの方法は、サブスレッドでUIを更新することは、メインスレッドでhandleMessage更新UIを呼び出すことに等しい.その原理は、非同期メッセージ処理メカニズムによって実現される.
Handler+ThreadとHandlerThreadの違い:HandlerThreadはメッセージキューを含むLooperとThreadをカプセル化した書き方であり、サブスレッドの受信したメッセージ処理に直接時間のかかるタスクを処理することができる.
Handler+ThreadとAsyncTaskの長所と短所:1,AsyncTaskは、Androidが提供する軽量級の非同期クラスであり、AsyncTaskクラスを直接継承して非同期操作を行い、インタフェースフィードバックの現在の非同期実行の程度(インタフェースによってUIの進捗更新を実現できる)を提供し、最後に実行の結果をUIメインスレッドにフィードバックする.使用の利点:簡単で、速い(コード上軽量であるが、実際にはhandlerよりもリソースを消費する)、プロセス制御可能な使用の欠点:複数の非同期操作を使用し、UI変更を必要とする場合、複雑になる.2,Handler+Threadは構造がはっきりしていて、機能定義がはっきりしていて、複数のバックグラウンドタスクに対して、簡単で、はっきりした使用の欠点:単一バックグラウンドの非同期処理の時、コードが多すぎて、構造が複雑すぎる(相対性)
名詞解釈:Messageはスレッド間で伝達されるメッセージであり、内部で少量の情報を携帯し、異なるスレッド間でデータを交換することができる.MessageQueueはメッセージキューで、Handlerによって送信されたすべてのメッセージを格納するために主に使用されます.このメッセージはメッセージキュー内で処理されるのを待っています.Handlerは、主にメッセージの送信および処理に使用される処理者である.送信メッセージは一般にhandlerのsendMessage()を使用し、処理メッセージはhandleMessage()を呼び出す.LooperはスレッドごとにMessageQueueの執事であり,loop()メソッドを呼び出すと無限ループに入り,MessageQueueにメッセージが存在することを発見するたびに取り出しhandleMessage()メソッドに渡す.
注意:各スレッドにはLooperオブジェクトとMessageQueueが1つしかありません.Handlerは作成時に存在するスレッドに依存する.
コード例の原理を使ってみましょう.
ターゲットシーン:メインスレッドはサブスレッドにメッセージを送信し、サブスレッドはメインスレッドのメッセージを受信した後、メインスレッドに通知を送信し、メインスレッドはUIを更新します.
実装手順:1,メインスレッドはサブスレッドにメッセージを送信し,サブスレッドはメッセージを受信する.サブスレッド受信メッセージである以上、handleMessageはサブスレッドにあることを示す.Handlerはサブスレッドに依存する.コードは次のとおりです.
private LoopThread loopThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
// Runnable
new Thread(loopThread = new LoopThread()).start();
}
/**
* Runnable
*/
public class LoopThread implements Runnable {
public Handler mHandler = null;
@Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
handleMsgAndTodo(msg);
}
};
Looper.loop();
}
}
Runnableインタフェースを実装したサブスレッドで、handlerがインスタンス化され、handleMessageを介してメッセージが受信されます.ここにLooperがありますprepare();ロoperとloop();説明は、サブスレッド自体が新しく作成したメッセージ執事looper(メインスレッドにはデフォルトで独自のlooperが作成されています)です.プライマリ・スレッドからメッセージを送信すると、直接呼び出すことができます.mHandler.sendEmptyMessage(1);”(LoopThreadはRunnableインタフェースを実現したクラスである).
次に,サブスレッド受信処理メッセージとメインスレッド処理メッセージの両方がhandleMsgAndTodo(msg)メソッドにカプセル化される.コードは次のとおりです.
/**
*
* @param msg
*/
private void handleMsgAndTodo(Message msg) {
switch (msg.what) {
case 0:
showMessageTv.setText("2--- UI");
Log.d(" ", " ");
break;
case 1:
Log.d(" ", " ");
handler.sendEmptyMessage(0);
Log.d(" ", " ");
break;
default:
break;
}
}
ホストからのメッセージmsg.what=1,ここでメッセージを受信するとすぐにメインスレッドにメッセージmsgを送信する.0であることに注意してmHandlerやloopThreadではなくhandlerを使用します.mHandler,ここでhandlerはメインスレッドでインスタンス化されている.コードは次のとおりです.
/**
* UI
*/
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
handleMsgAndTodo(msg);
}
};
ここでhandlerはメインスレッドに依存しており,UIを直接更新することができる.また,非同期メッセージメカニズムに基づいたいくつかの方法もある.例えば、サブスレッドでUIを更新する例:
/**
* hander.post() UI
*/
private void handerpost() {
new Thread(new Runnable() {
@Override
public void run() {
//... ,
// handler.sendEmptyMessage(0);
// UI handleMessage() UI——hander.post(),view.post(), runOnUiThread(), 。
// handler.post(new Runnable() {
// @Override
// public void run() {
// showMessageTv.setText("1--- UI");
// }
// });
// new Handler(Looper.getMainLooper()) handleMessage() UI , Handler 。
Handler handler2 = new Handler(getMainLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
showMessageTv.setText("3--- UI");
}
};
handler2.sendEmptyMessage(0);
}
}).start();
}
上記のいくつかのコードの方法は、プライマリスレッドのhandlerを呼び出してメッセージ更新UIを送信することにほかならない.サブスレッドでインスタンス化されたもう1つのhandler 2も、メインスレッドのlooper、すなわちメインスレッドと同じメッセージキューを維持することを共用しているため、メインスレッドでUIを更新することに相当する.
自己理解:どのスレッドがメッセージを受信するかは、そのスレッドでhandleMessageを呼び出すためにHandlerをインスタンス化します.メインスレッドがサブスレッドにメッセージを送る場合はLooperを使用する必要がある.prepare()とLooper.loop()は、handleMessage()を呼び出すために、Handlerをサブスレッドにインスタンス化する.
サブスレッドではnew Handler(Looper.getMainLooper()はそのhandleMessage()メソッドのことがメインUIスレッドで処理されていることを示し,このHandlerは実はメインスレッドにバインドされている.hander.post(),view.post()、runOnUI Thread()のいくつかの方法は、サブスレッドでUIを更新することは、メインスレッドでhandleMessage更新UIを呼び出すことに等しい.その原理は、非同期メッセージ処理メカニズムによって実現される.
Handler+ThreadとHandlerThreadの違い:HandlerThreadはメッセージキューを含むLooperとThreadをカプセル化した書き方であり、サブスレッドの受信したメッセージ処理に直接時間のかかるタスクを処理することができる.
Handler+ThreadとAsyncTaskの長所と短所:1,AsyncTaskは、Androidが提供する軽量級の非同期クラスであり、AsyncTaskクラスを直接継承して非同期操作を行い、インタフェースフィードバックの現在の非同期実行の程度(インタフェースによってUIの進捗更新を実現できる)を提供し、最後に実行の結果をUIメインスレッドにフィードバックする.使用の利点:簡単で、速い(コード上軽量であるが、実際にはhandlerよりもリソースを消費する)、プロセス制御可能な使用の欠点:複数の非同期操作を使用し、UI変更を必要とする場合、複雑になる.2,Handler+Threadは構造がはっきりしていて、機能定義がはっきりしていて、複数のバックグラウンドタスクに対して、簡単で、はっきりした使用の欠点:単一バックグラウンドの非同期処理の時、コードが多すぎて、構造が複雑すぎる(相対性)