handler的基本使用
1.Handler是什么?
主要是为了接受子线程的消息,配合主线程更新UI。
在Android系统内,主线程应该专注于更新UI,而不会把精力放到,请求网络,或者本地文件上,从而阻塞自己,使得自己的应用出现anr(application not responding)的情况。
还有就是Android中Android UI组件是线程不安全的,也就是说,更新UI的操作希望只在主线程中进行,而不希望在子线程中进行,Handler自然而然的就出现了。
2.Handler、Looper、MessageQueue 与 Message
looper:循环读取消息,交由Handler处理,一个线程对应一个looper
MessageQueue:消息队列,一个looper对应一个消息队列
Message:消息,一个消息队列有多个消息
Handler:处理与分发消息,每个消息最多指定一个handler处理
3.handler中的方法
post系列
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
Send系列
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
可以看一下post(Runable r)的实现
public final boolean post(Runable r)
{
return sendMessageDelayed(getPostMessage(r),long)
}
//而getpostMessage则是将runable包装成message
private static Message gerPostMessage(Runnable r)
{
Message m = Message.obtain();
m.callback = r;
return m;
}
在处理message的时候,如果Message.callback不为空则使用这个将优先使用callba来处理
Handle.mcallback不为空则使用mcallback处理
如果前两个都不存在则使用handleMessage处理
4.handler的构造方法
4.1 handler是如何与Looper联系起来的,这个主要在构造方法里面。
4.2 先看一下handler类的成员变量
public class Handler{
//...部分
final MessageQueue mQueqe;
final Looper mLooper;
//这里就上上述的mcallback
final CallBack mcallback;
}
4.3Handler 的构造方法
//handler有多个构造方法
public Handler();
public Handler(Callback callback);
public Handler(Looper looper);
public Handler(Callback callback,Looper looper);
//我们来看一个public Handler()
public Handler()
{
//...部分
mLooper = Looper.myLooper();//获取当前线程中的Looper实例
mQueue = Looper.mQueue;
}
//对于下面的例子便是使用了这个构造函数, 并获取了UI主线程的Looper
//对于普通线程来说,我们需要自己开启线程对应的looper
class LooperThread extends Thread
{
public Handler mHandler;
public void run()
{
//主线程使用Looper.prepareMainLooper()
Looper.prepare();
mHandler = new Handler(){ //重写处理消息方法};
Looper.loop();//进入消息循环
}
}
5.基本使用
5.1MyThread子线程
package com.example.myhandler;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class MyThread extends Thread{
private Handler myHandler;
public MyThread(Handler h) {
// TODO Auto-generated constructor stub
this.myHandler = h;
}
@Override
public void run() {
super.run();
while(true)
{
Message m = new Message();
m.what = 0x1010;
Bundle data = new Bundle();
data.putString("mes", "我是新消息");
m.setData(data);
try {
//睡眠一秒钟
Thread.sleep(1000);
//再发送消息
myHandler.sendMessage(m);
Log.i("sss", "122212");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
5.2.MainActivity
package com.example.myhandler;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textview;
Button btn;
Handler myHandler ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView)findViewById(R.id.textview);
btn = (Button)findViewById(R.id.btn);
myHandler = new Handler(MainActivity.this.getMainLooper())
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == 0x1010)
{
textview.append(msg.getData().getString("mes"));
}
}
};
//持有handler的引用可以向他这个线程的looper发送消息
MyThread tt = new MyThread(myHandler);
tt.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}