androidのHandler
【回る:】http://www.cnblogs.com/keyindex/articles/1822463.html
前言
Androidを勉強しています.Androidの応用はどのように設計されているのかを知るために、いくつかのオープンソースのAndroidアプリケーションを詳しく調べることにしました.いくつかのオープンソースアプリケーションから点を吸収し、量の蓄積を行いながら、Androidの学習研究の方向を探っています.ここでまずjwoodのStandup Timerプロジェクトを選びました.本論文では研究内容をノートに整理し、インデックスリストを作成します.
キーワード
Android.os.Handlerは多くの知識点に関連しています.いくつかのキーワードを下記に挙げて、Handlerを紹介します.
android.os.Handler、android.os.Handler.Clalback
ループ、
Threadle、Runnable
Message、Message queue
android.os.Handler
Handlerはandroidでメッセージの送信と処理を担当しています.その主な用途は:
1)計画通りにメッセージを送信するか、またはRunnableを実行する(POST方法を使用する).
2)他のスレッドから送信されたメッセージは、スレッド衝突を避けるためにメッセージキューに入れられる(UIスレッドを更新するのが一般的である).
デフォルトでは、Handlerは現在のスレッドでのメッセージサイクルの例(Handler(Looper looper)、Handler(Looper looper,Handler.Clalback calback)を使用してスレッドを指定することができます.一方、メッセージ・キューは現在のスレッドの複数のオブジェクトによって配布、処理されます.(UIスレッドでは、システムは既にActivityで処理されています.いくつかのHandlerを起こして処理してもいいです.)を選択します.Handlerを実装する場合、Looperは任意のスレッドであってもいいです.Handlerのポインタがあれば、どのスレッドでもsendMessageができます.HandlerのMessageに対する処理は同時に行われません.一つのLooperは一つのMessageを処理してから次のストリップを読みます.したがって、利息解消の処理はブロッキング形式です.方法には時間のかかる操作があってはならず、時間のかかる操作を他のスレッドに置いて実行し、操作が終わったらMessage(sendMessags方法を通じて)を送信し、その後、handleMessage(UI)によって更新することができる.
カウントダウンプログラム
Timerを用いてカウントダウンプログラムを作成し、TimerとTimerTaskを用いてカウントダウンを行い、sendMessages方法を用いてメッセージを送信し、HanleMessageでUIを更新する.
Activityレイアウト:
Layout
onCreate
メッセージを送信
ICallBackインターフェースとTaskクラス
実行結果
OneCreate方法では、スレッドのIDは1(UIスレッド)であり、これはHandlerMessageがメッセージ処理を行う際に作成したスレッドIDと同じであり、メッセージ送信のスレッドIDは8非UIスレッドであることがわかる.
Threadleを使って実現します.
Activity類
POSTについて
Postの様々な方法は、Runnableをメッセージキューに送信し、到着時に処理することである.
POST
コード
参考文献
Androidはノートのメッセージの仕組み、非同期とマルチスレッドを勉強します.
android handler概念解釈
SDK
前言
Androidを勉強しています.Androidの応用はどのように設計されているのかを知るために、いくつかのオープンソースのAndroidアプリケーションを詳しく調べることにしました.いくつかのオープンソースアプリケーションから点を吸収し、量の蓄積を行いながら、Androidの学習研究の方向を探っています.ここでまずjwoodのStandup Timerプロジェクトを選びました.本論文では研究内容をノートに整理し、インデックスリストを作成します.
キーワード
Android.os.Handlerは多くの知識点に関連しています.いくつかのキーワードを下記に挙げて、Handlerを紹介します.
android.os.Handler、android.os.Handler.Clalback
ループ、
Threadle、Runnable
Message、Message queue
android.os.Handler
Handlerはandroidでメッセージの送信と処理を担当しています.その主な用途は:
1)計画通りにメッセージを送信するか、またはRunnableを実行する(POST方法を使用する).
2)他のスレッドから送信されたメッセージは、スレッド衝突を避けるためにメッセージキューに入れられる(UIスレッドを更新するのが一般的である).
デフォルトでは、Handlerは現在のスレッドでのメッセージサイクルの例(Handler(Looper looper)、Handler(Looper looper,Handler.Clalback calback)を使用してスレッドを指定することができます.一方、メッセージ・キューは現在のスレッドの複数のオブジェクトによって配布、処理されます.(UIスレッドでは、システムは既にActivityで処理されています.いくつかのHandlerを起こして処理してもいいです.)を選択します.Handlerを実装する場合、Looperは任意のスレッドであってもいいです.Handlerのポインタがあれば、どのスレッドでもsendMessageができます.HandlerのMessageに対する処理は同時に行われません.一つのLooperは一つのMessageを処理してから次のストリップを読みます.したがって、利息解消の処理はブロッキング形式です.方法には時間のかかる操作があってはならず、時間のかかる操作を他のスレッドに置いて実行し、操作が終わったらMessage(sendMessags方法を通じて)を送信し、その後、handleMessage(UI)によって更新することができる.
カウントダウンプログラム
Timerを用いてカウントダウンプログラムを作成し、TimerとTimerTaskを用いてカウントダウンを行い、sendMessages方法を用いてメッセージを送信し、HanleMessageでUIを更新する.
Activityレイアウト:
Layout
<?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" >
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/txt" />
<Button
android:id="@+id/btnStartTime"
android:text=" "
android:layout_width="80dip" android:layout_height="wrap_content" >
</Button>
<Button
android:id="@+id/btnStopTime"
android:text=" "
android:layout_width="80dip" android:layout_height="wrap_content" />
<SeekBar android:id="@+id/SeekBar01" android:layout_width="match_parent" android:layout_height="wrap_content">
</SeekBar>
</LinearLayout>
ここではTextViewを使ってカウントダウンの時間変化を表示します.2つのボタンは時間の開始と停止を制御します.SeekBarは主にスレッドがブロックされているかどうかを確認します.onCreate
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.txt);
btnStart = (Button) findViewById(R.id.btnStartTime);
btnStop = (Button) findViewById(R.id.btnStopTime);
Log.d("ThreadId", "onCread:"
+ String.valueOf(Thread.currentThread().getId()));
myHandler = new Handler(this);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
onCreate方法で元素の一つの元素を初期化します.myHandler=new Handler(this)と呼びます. Handler(Handler.Clalback calback)コンストラクタは、コールバックで送られてきたメッセージを処理します(これでは、内部的な書き方でHandleMessage()を書き換える必要はありません).したがって、Activityは、android.os.Handler.Clalbackインターフェースを実現しなければならない.また、onCreateメソッドのThreadIdをLogに記録し、メッセージ送信、処理時に作成したスレッドと比較している.メッセージを送信
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartTime:
startTimer();
break;
case R.id.btnStopTime:
timer.cancel();
break;
}
}
private synchronized void startTimer() {
timer = new Timer();
// TimerTask
updateTimerValuesTask = new TimerTask() {
// @Override
// public void run() {
// updateTimerValues();
// }
//
// };
// CallBack 。Task TimerTask
Task updateTimerValuesTask = new Task(this);
timer.schedule(updateTimerValuesTask, 1000, 1000);
}
// 。
private void updateTimerValues() {
total--;
Log.d("ThreadId", "send:"
+ String.valueOf(Thread.currentThread().getId()));
Message msg=new Message();
Bundle date = new Bundle();
//
date.putInt("time", total);
msg.setData(date);
msg.what=0;
myHandler.sendMessage(msg);
//
// Message msg=myHandler.obtainMessage();
// Bundle date = new Bundle();
//
// date.putInt("time", total);
// msg.setData(date);
// msg.what=0;
// msg.sendToTarget();
}
@Override
public void TaskRun() {
updateTimerValues();
}
Buttonボタンのイベント処理を実現し、カウントダウン動作に入ります.ここで使用するTimerは、タイミング操作を実行します.TaskはTimerTaskクラスを継承しています.タスク処理インターフェースを追加して、リカバリーモードを実現します.このActivityは、このリカバリーインターフェースITaskCallBackを実現する必要があります.(このようにするのは、内部の編纂方法があまり好きではないからです).ICallBackインターフェースとTaskクラス
public interface ITaskCallBack {
void TaskRun();
}
public class Task extends TimerTask {
private ITaskCallBack iTask;
public Task(ITaskCallBack iTaskCallBack) {
super();
iTask=iTaskCallBack;
}
public void setCallBack(ITaskCallBack iTaskCallBack) {
iTask=iTaskCallBack;
}
@Override
public void run() {
// TODO Auto-generated method stub
iTask.TaskRun();
}}
Java 。
CallBack
/** * */
@Override
public boolean handleMessage(Message msg) {
switch(msg.what)
{
case 0:
Bundle date=msg.getData();
txt.setText(String.valueOf(date.getInt("time")));
Log.d("ThreadId", "HandlerMessage:"
+ String.valueOf(Thread.currentThread().getId()));
Log.d("ThreadId", "msgDate:" + String.valueOf(date.getInt("time")));
break;
}
return false;
}
Android.os.Handler.calbackインターフェースの実現が見られますが、実はhandlee Message()メソッドを書き換えています.実行結果
OneCreate方法では、スレッドのIDは1(UIスレッド)であり、これはHandlerMessageがメッセージ処理を行う際に作成したスレッドIDと同じであり、メッセージ送信のスレッドIDは8非UIスレッドであることがわかる.
Threadleを使って実現します.
Activity類
/*
* : ThreadHandlerrActivity.java
* : 2014-1-6
*/
package com.example.jiji;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ThreadHandlerrActivity extends Activity implements Callback,
OnClickListener {
private TextView txt;
private Button btnStart, btnStop;
private Handler myHandler;
private TimerThread timerThread;
private int Total = 30;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.txt);
btnStart = (Button) findViewById(R.id.btnStartTime);
btnStop = (Button) findViewById(R.id.btnStopTime);
Log.d("ThreadId",
"onCread:" + String.valueOf(Thread.currentThread().getId()));
myHandler = new Handler(this);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
/** * */
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 0:
Bundle date = msg.getData();
txt.setText(String.valueOf(date.getInt("time")));
Log.d("ThreadId",
"HandlerMessage:"
+ String.valueOf(Thread.currentThread().getId()));
Log.d("ThreadId", "msgDate:" + String.valueOf(date.getInt("time")));
break;
}
return false;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartTime:
//
timerThread = new TimerThread(myHandler, 60);
timerThread.start();
break;
case R.id.btnStopTime:
timerThread.stopThread();
// timerThread.destroy();
break;
}
}
}
カスタムスレッドクラス
/*
* : TimerThread.java : 2014-1-6
*/
package com.example.jiji;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* * , Handler, Total
* */
public class TimerThread extends Thread {
public int Total = 60;
public Handler handler;
/**
* *
*
* @param mhandler
* handler
** @param total
*
*/
public TimerThread(Handler mhandler, int total) {
super();
handler = mhandler;
Total = total;
}
public void stopThread() {
Total = -1;
}
@Override
public void run() {
while (true) {
Total--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (Total < 0)
break;
Message msg = new Message();
Bundle date = new Bundle();
//
date.putInt("time", Total);
msg.setData(date);
msg.what = 0;
Log.d("ThreadId",
"Thread:" + String.valueOf(Thread.currentThread().getId()));
handler.sendMessage(msg);
}
super.run();
}
}
ここではThread類を継承していますが、Runnableインターフェースも直接実現できます.POSTについて
Postの様々な方法は、Runnableをメッセージキューに送信し、到着時に処理することである.
POST
/*
* : PostHandler.java
* : 2014-1-6
*/
package com.example.jiji;
import java.util.Timer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class PostHandler extends Activity implements OnClickListener, Runnable {
private TextView txt;
private Button btnStart, btnStop;
private Handler myHandler;
private Timer timer;
private int total = 60;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.txt);
btnStart = (Button) findViewById(R.id.btnStartTime);
btnStop = (Button) findViewById(R.id.btnStopTime);
Log.d("ThreadId",
"onCread:" + String.valueOf(Thread.currentThread().getId()));
myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
Bundle date = msg.getData();
txt.setText(String.valueOf(date.getInt("time")));
Log.d("ThreadId",
"HandlerMessage:"
+ String.valueOf(Thread.currentThread()
.getId()));
Log.d("ThreadId",
"msgDate:" + String.valueOf(date.getInt("time")));
break;
}
}
};
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartTime:
// myHandler.post(this);
myHandler.postDelayed(this, 1000);
break;
case R.id.btnStopTime:
break;
}
}
@Override
public void run() {
while (true) {
total--;
if (total < 0)
break;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = new Message();
Bundle date = new Bundle();
//
date.putInt("time", total);
msg.setData(date);
msg.what = 0;
Log.d("ThreadId",
"POST:" + String.valueOf(Thread.currentThread().getId()));
myHandler.sendMessage(msg);
Log.d("ThreadId",
"Thread:" + String.valueOf(Thread.currentThread().getId()));
}
}
}
POSTを使うとRunnableを処理スレッド(ここはUI)に一緒に送信し、Runnableの操作が時間がかかるとスレッドがブロック状態になります.RunnableのRunメソッドを先に実行してからHandleMessage()に入るのが見えます.他の書き込みも試してみました.TimerThreadPOSTを過去に行っても、運転結果は同じです.コード
/*
* : PostHandler.java
* : 2014-1-6
*/
package com.example.jiji;
import java.util.Timer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class PostHandler extends Activity implements OnClickListener, Runnable {
private TextView txt;
private Button btnStart, btnStop;
private Handler myHandler;
private Timer timer;
private int total = 60;
private TimerThread timerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView) findViewById(R.id.txt);
btnStart = (Button) findViewById(R.id.btnStartTime);
btnStop = (Button) findViewById(R.id.btnStopTime);
Log.d("ThreadId",
"onCread:" + String.valueOf(Thread.currentThread().getId()));
myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
Bundle date = msg.getData();
txt.setText(String.valueOf(date.getInt("time")));
Log.d("ThreadId",
"HandlerMessage:"
+ String.valueOf(Thread.currentThread()
.getId()));
Log.d("ThreadId",
"msgDate:" + String.valueOf(date.getInt("time")));
break;
}
}
};
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartTime:
// myHandler.post(this);
// myHandler.postDelayed(this, 1000);
timerThread = new TimerThread(myHandler, 60);
myHandler.post(timerThread);
break;
case R.id.btnStopTime:
break;
}
}
@Override
public void run() {
while (true) {
total--;
if (total < 0)
break;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = new Message();
Bundle date = new Bundle();
//
date.putInt("time", total);
msg.setData(date);
msg.what = 0;
Log.d("ThreadId",
"POST:" + String.valueOf(Thread.currentThread().getId()));
myHandler.sendMessage(msg);
Log.d("ThreadId",
"Thread:" + String.valueOf(Thread.currentThread().getId()));
}
}
}
POSTの様々な方法は主に「計画通りにメッセージを送信するか、またはあるRunnableを実行する(POST方法を使用する)」ために使用されると言える.参考文献
Androidはノートのメッセージの仕組み、非同期とマルチスレッドを勉強します.
android handler概念解釈
SDK