4.Handler移除消息
handler不只能发送一个消息,而且还能移除消息。当我们调用handler.post()方法时,调用handler.removeCallbacks(myRunnable)方法,可以移除正在调用的对象。当调用handler.sendMessage()方法时,可以通过调用
handler.removeMessages(int )方法移除正在调用的对象;
实例五:拦截消息
布局代码:
"http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:text="hello" />
java逻辑代码:
public class MainActivity extends Activity implements OnClickListener{
private Button intercept,send;
private TextView tv;
Handler handler = new Handler(){
public void handleMessage(Message msg) {
if (msg.what ==1) {
tv.setText(msg.obj+"");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intercept = (Button)findViewById(R.id.intercept);
send = (Button)findViewById(R.id.send);
send.setOnClickListener(this);
intercept.setOnClickListener(this);
tv = (TextView)findViewById(R.id.textView1);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send:
new Thread(){
public void run() {
Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = "你拦截不到,哈哈哈";
handler.sendMessageDelayed(msg, 5000);
}
}.start();
break;
case R.id.intercept:
//移除一条信息
handler.removeMessages(1);
break;
default:
break;
}
}
}
5.Handler移除消息内容
上述的例子展示的是handler如何移除一条消息的对象,除此之外我们也可以拦截消息内容。
实例六:拦截消息内容
布局代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="send"
android:text="发送消息" />
RelativeLayout>
java逻辑代码:
public class MainActivity extends Activity {
//传递消息内容的拦截,返回值为false不拦截,为true就拦截
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.i("tag", "handle--1:"+msg.arg1);
if (msg.what>100) {
return false;
}
return true;
}
}){
public void handleMessage(Message msg) {
Log.i("tag", "handle--2:"+msg.arg1);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void send(View view){
new Thread(){
public void run() {
Message message = Message.obtain();
message.arg1 = 98;
handler.sendMessage(message);
}
}.start();
}
}
初始化handler的对象时,传入callback参数,重写callback中的handlemessage的方法,如果返回值设置为false不拦截消息,如果返回值设置为true,则拦截。
6.Handler的原理是什么?
Handler封装了消息的发送,主要包括消息发送给谁
Looper类主要用于一个线程循环获取消息队列中的消息。
Looper的作用主要是负责管理消息队列,负责消息的出列和入列操作。
MessageQueue:就是一个消息队列,可以添加消息,并处理消息。
Message是线程之间传递信息的载体,包含了对消息的描述和任意的数据对象。
总结:
Handler 负责发送消息,looper负责接收handler发送的消息,并直接把消息传递给handler自己,MessageQueue就是一个存储消息的容器。
Looper的知识:
1.每个线程有且最多只能有一个Looper对象,它是一个ThreadLocal
2.Looper内部有一个消息队列,loop()方法调用后线程开始不断从队列中取出消息执行
3.Looper使一个线程变成Looper线程。
7. 如何实现一个与线程相关的handler
所谓的消息机制其实很简单,实现这种机制需要只需要五步:
1、调用Looper.prepare(),线程变成循环线程;
2、实例化Handler,这里需要覆盖handleMessage方法,处理收到的消息;
3、 调用Looper.loop();使线程进入循环;
4、 实例化Message对象,调用已经实例化好的handler对象的obtainMessage方法,把数据传给obtainMessage方法,obtainMessage方法就会实例化一个Message对象。(这里也可以发送实现Runnable接口的对象);
5、调用Handler的sendMessage方法把实例化好的Message对象发送出去。
实例七:如何实现一个handler与自定义线程相关联
逻辑代码:
public class MainActivity extends Activity {
MyThread thread;
Handler handler = new Handler(){
public void handleMessage(Message msg) {
Log.i("tag", "Thread:"+Thread.currentThread().getName());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
thread = new MyThread();
thread.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.handler.sendEmptyMessage(1);
handler.sendEmptyMessage(1);
}
class MyThread extends Thread{
public Handler handler;
@Override
public void run() {
super.run();
Looper.prepare(); //把普通线程变成looper线程
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.i("tag", "Thread:"+Thread.currentThread().getName());
}
};
Looper.loop(); //使looper线程循环
}
}
}
初学者在学习handler消息机制时,往往会产生一个误区,认为只有主线程才有handler,才能够实现通信,通过上面的例子,我们可以看出在子线程中同样也有handler,但是需要实现线程添加looper,才能够得到该线程中的handler。
8. Android中更新ui的几种方式。
handler post( );
handler sendMessage( );
view post( );
runOnUiThread( );
包含以上四种方式,前两种与handler相关。第三种一般在主线程中调用,避免因为线程嵌套出现线程错乱的现象,第四种会回到主线程中执行。
实例八:Android中更新ui的方式
逻辑代码:
public class MainActivity extends Activity {
private TextView tv;
Handler handler = new Handler(){
public void handleMessage(Message msg) {
tv.setText("handler sendmessage update ui");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.tv);
// new Thread(){
// public void run() {
// handlerSendMessage(); //第一种
// handlerPost(); //第二种
// runOnUiThreadUpdateUi(); //第三种
// }
// }.start();
viewPost(); //第四种
}
/***
* 通过handler的sendMessage发送数据,更新ui
* */
public void handlerSendMessage(){
handler.sendEmptyMessage(1);
}
/***
* 通过handler的post方法,更新ui
* */
public void handlerPost(){
handler.post(new Runnable() {
@Override
public void run() {
tv.setText("handler post update ui");
}
});
}
/**
* runOnUiThreadUpdateUi回到主线程,更新ui
* */
public void runOnUiThreadUpdateUi(){
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText("runOnUiThread update ui");
}
});
}
/**
* view的post方法,更新ui
* */
public void viewPost(){
tv.post(new Runnable() {
@Override
public void run() {
tv.setText("view post update ui");
}
});
}
}
以上为handler的使用方法和消息处理机制的原理,更多相关代码资源请下载:
http://download.csdn.net/detail/u012156341/9447357