•使用Handler是异步的,它会建立新线程么?
•Handler是在主线程内么?
Handler的post和sentMessage方法,使用的是一个队列还是两个?
是一个队列,post是线程队列,sentMessage是消息队列
•子线程中建立一个handler,然后sendMessage会怎样?
子线程建立handler,构造的时候传入主线程的,Looper
•Handler是做什么的,既然是异步任务处理,他本身是多线程的么?
Handler作用
1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器
2)线程间通信。在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息。 当你创建子线程时,你可以在你的子线程中拿到父线程中创建的Handler对象,就可以通过向父线程的消息队列发送消息了。 由于Android要求在UI线程中更新界面,因此,可以通过该方法在其他线程中更新界面。
一、角色描述
2.Handle、 Looper 、Message Queue和线程之间的关系
1).Looper(相当于隧道)一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(车队、消息隧道).
•当前线程中有一个Looper这样的循环在监听消息队列,但又不是额外的线程,这不是和我们的学习常理相勃吗?
Looper没有新开一个线程,Looper又系统来控制的循环。
2).Handler 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper(从Message Queue取出)所送来的消息.
3).Message Queue(消息队列): 用来存放线程放入的消息。
4).线程: UI thread 通常就是main thread, 而Android启动程序时会替它建立一个Message Queue.
每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。
见下面两张图,你将明白Handler作用,.Message Queue,.Looper
3.主线程里面定义两个不同的handler实例,其中一个handler发出的消息另外一个能接收到吗?
不能,虽然主线程共享同一个消息队列,但是它们通过message的what变量来区分到底是由哪一个handler发出的消息。Handler实例与消息处理是关联的,发送和接收要匹配
mainHandler2 = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg);//这里接收不到 Toast.makeText(HandlerConceptActivity.this, "[Main Thread]Handler2 Get the message: "+msg.getData().getString(HANDLER_KEY), 5000).show() ; } } ; mainHandler1 = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg);//这里能接收到 Toast.makeText(HandlerConceptActivity.this, "[Main Thread]Handler1 Get the message: "+msg.getData().getString(HANDLER_KEY), 5000).show() ; } } ; //Handler Lab1 findViewById(R.id.buttonHandlerLab1).setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub mainHandler1.sendMessage(defineNewMessage("Lab1")) ; //try to use mainHanlder2 to send meesage and receive . //mainHandler2.sendMessage(defineNewMessage("Lab1")) ; } }).start() ; } }) ; 4.任何一个线程都有消息队列吗 默认只有主线程才有消息队列,自己新建的普通线程是没有线程队列的。不过子线程中用HandlerThread,默认有消息队列
1)//下面代码会抛出Can't create handler inside thread that has not called Looper.prepare()异常
findViewById(R.id.buttonHandlerLab2).setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(new Runnable(){ @Override public void run() { Handler lab2Handler = new Handler() ; lab2Handler.sendMessage(defineNewMessage("Lab2")) ; } }).start() ; } }) ;
2)下面的代码是正确的
class SubHandlerThread extends HandlerThread{ public SubHandlerThread(String name) { super(name); // TODO Auto-generated constructor stub } @Override public void run() { // TODO Auto-generated method stub ProcessCaculate() ; Looper lp = this.getLooper() ; new Handler(lp){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.i(CommonConstants.LOGCAT_TAG_NAME, "Get the message by HandlerThread "+ msg.getData().getString(HANDLER_KEY)) ; } }.sendMessage(defineNewMessage("Lab2.2")) ; } }
findViewById(R.id.buttonHandlerLab3).setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stub//using HandlerThread to make handler (message queue) ,send messageSubHandlerThread subHandlerThread = new SubHandlerThread("threadone"); subHandlerThread.start();}}) ;
5.子线程的handler可以使用主线程的消息队列吗
可以的。
//Handler Lab3.1 child thread get main thread's looper and send message . findViewById(R.id.buttonHandlerLab4).setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub Handler lab3Handler ; lab3Handler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.i(CommonConstants.LOGCAT_TAG_NAME, "Get the message: "+msg.getData().getString(HANDLER_KEY)+" by Child Thread Handler") ; } }; lab3Handler.sendMessage(defineNewMessage("Lab3")) ; } }).start() ; } }) ;
5.子线程的handler可以使用子线程的消息队列吗
//Handler Lab3.2 using looper.prepare() and looper.loop() . findViewById(R.id.buttonHandlerLab5).setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(new Runnable(){ @Override public void run() { Looper.prepare();//实例化looper对象,生成消息队列 lab3Handler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.i(CommonConstants.LOGCAT_TAG_NAME, "Get the message from "+msg.getData().getString(HANDLER_KEY)+" by Child Thread Handler") ; } } ; lab3Handler.sendMessage(defineNewMessage("Lab3")) ; Looper.loop() ;//循环消息队列 } }).start() ; } }) ;
总结:
1.Handler实例与消息处理是关联的,发送和接收要匹配。
2.Handler操作队列,主要是在子线程操作主线程消息队列
3.子线程默认是没有消息队列的