网友通过本文主要向大家介绍了android handler机制,android中handler机制,android handler,android handler用法,android handler详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
Android消息机制Handler解析(源码+Demo)
Handler是开发人员在面试过程中最常见的问题之一了,这篇文章将较为全面地对Handler进行解读,包括源码层,以及使用方法。
如果看完文章有疑问,欢迎在评论中一起探讨
基本内容包括:
看完文章之后,可以用这个图片进行复习。
</div> 一、什么是Handler</div> Handler是Android提供用来更新UI的一套机制,也是一套消息处理机制,可以用它来发送消息,也可以用它来接收消息。</div> </div> 二、为什么使用Handler</div> Android在设计之时,就封装了一套消息的创建、传递、处理机制,若不遵循这样的处理机制,就没办法更新UI信息,并且会抛出异常</div> </div> 三、Handler用法</div> 1、postdelayed()延时发送执行子线程</div> </div> 文字轮询Demo(实现每隔一秒钟更新一次Textview的功能)</div>public class MainActivity extends AppCompatActivity { private TextView mTextView; private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }; private String[] str = new String[]{"傲慢","偏见","僵尸"}; private int index = 0; MyRunnable myRunnable = new MyRunnable(); private class MyRunnable implements Runnable{ @Override public void run() { index = index % 3; mTextView.setText(str[index]); index ++; mHandler.postDelayed(myRunnable,1000); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv); mHandler.postDelayed(myRunnable,1000); } }
2、sendMessage()回调handleMessage()传递消息</div> Demo:在子线程中得到信息,发送至主线程,更新textview的内容</div>
public class MainActivity extends AppCompatActivity { private TextView mTextView; Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { mTextView.setText(msg.obj+""+ "arg1="+msg.arg1 + " arg2="+msg.arg2); super.handleMessage(msg); } }; private class Person{ String name; int age; @Override public String toString() { return "name="+name+" age="+age; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv); new Thread(){ @Override public void run() { Message msg = new Message(); msg.arg1 = 1; msg.arg2 = 2; Person person = new Person(); person.name = "pig"; person.age = 10; msg.obj = person; mHandler.sendMessage(msg); } }.start(); } }

3、sendToTarget()传递消息</div> 与第二种用法原理一致</div>
public class MainActivity extends AppCompatActivity { private TextView mTextView; Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { mTextView.setText(msg.obj+""+ "arg1="+msg.arg1 + " arg2="+msg.arg2); super.handleMessage(msg); } }; private class Person{ String name; int age; @Override public String toString() { return "name="+name+" age="+age; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv); new Thread(){ @Override public void run() { Message msg = mHandler.obtainMessage();//同样可以获取Message对象 msg.arg1 = 1; msg.arg2 = 2; Person person = new Person(); person.name = "pig"; person.age = 10; msg.obj = person; msg.sendToTarget(); } }.start(); } }
4、使用CallBack截获Handler的消息
public class MainActivity extends AppCompatActivity { private TextView mTextView; Handler mHandler = new Handler(new Handler.Callback() { //传入CallBack对象,对于重载的返回值为bollean的handleMessage() //返回值为false,将先执行这个方法,再执行返回值为void的handleMessage()方法 //返回值为true,只执行这个方法 @Override public boolean handleMessage(Message msg) { Toast.makeText(MainActivity.this, "截获消息", Toast.LENGTH_SHORT).show(); return false; } }){ public void handleMessage(Message msg) { Toast.makeText(MainActivity.this, "发出消息", Toast.LENGTH_SHORT).show(); } }; private class Person{ String name; int age; @Override public String toString() { return "name="+name+" age="+age; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mHandler.sendEmptyMessage(0); } }); } }
四、为什么在Android中智能通过Handler机制在主线程中更新UI?</div> </div> 最根本的是解决多线程并发问题。</div> 假如在同一个Activity中,有多个线程同时更新UI,且没有加锁,那会导致什么问题呢?</div> UI更新混乱。</div> 假如加锁呢?</div> 会导致性能下降。</div> 使用Handler机制,我们不用去考虑多线程的问题,所有更新UI的操作,都是在 主线程消息队列中轮询去处理的。</div> </div> 五、Handler机制的原理</div> </div> 1、Handler封装了消息的发送(主要包括消息发送给谁)</div> Looper</div> (1)内部包含一个消息队列,即MessageQueue,所有Handler发送的消息都会进入这个队列</div> (2)Looper.loop方法,是一个死循环,不断从MessageQueue取出消息,如有消息就处理,没有就阻塞</div> </div> 2、MessageQueue,一个消息队列,可以添加消息,处理消息</div> </div> 3、Handler内部会跟Looper进行关联,也就是说,在Handler内部可以找到Looper,找到了Looper也就找到了MessageQueue,在Handler中发送消息,其实就是向Message发送消息,</div> </div> 总结:Handler负责发送消息,Looper负责接收消息,并把消息回传给Handler自己,而MessageQueue是一个存储消息的容器。</div> </div> </div> 源码层:</div> Android的应用程序是通过ActivityThread进行创建,在ActivityThread默认创建一个Main线程,一个Looper,所有更新UI的线程都是通过Main线程进行创建的。</div> 查看Looper.loop的源代码,发现确实是一个死循环</div>
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.