Handler机制的理解与使用
来源:互联网 发布:人工智能大学专业 编辑:程序博客网 时间:2024/05/22 11:47
一、为什么要用Handler
当应用程序启动时,会开启一个主线程(也就是UI线程),由她来管理UI,监听用户点击,来响应用户并分发事件等。所以一般在主线程中不要执行比较耗时的操作,如联网下载数据等,否则出现ANR(应用无响应)错误。所以就将这些操作放在子线程中,但是由于Android子线程是不安全的,所以只能在主线程中更新UI。Handler就是用来 子线程和创建Handler的线程进行通信的。
二、理解Handler机制的使用
开始今天的学习之前,我们先来了解一些概念:
Android是消息驱动的,实现消息驱动有几个要素:
消息的表示:Message
消息队列:MessageQueue
消息循环:用于循环取出消息进行处理:Looper
消息处理:消息循环从消息队列中取出消息后要对消息进行处理:Handler
handler类有两种主要用途:
1、按照时间计划,在未来某时刻,对处理一个消息或执行某个runnable实例。
2、把一个对另外线程对象的操作请求放入消息队列中,从而避免线程间冲突。
三、Handler机制的使用
Handler工具类在多线程中有两方面的应用:
1、发送消息,在不同的线程间发送消息,使用的方法为sendXXX();
android.os.Handler对象通过下面的方法发送消息的:
sendEmptyMessage(int),发送一个空的消息;
sendMessage(Message),发送消息,消息中可以携带参数;
sendMessageAtTime(Message, long),未来某一时间点发送消息;
sendMessageDelayed(Message, long),延时Nms发送消息。
2、计划任务,在未来执行某任务,使用的方法为postXXX();
android.os.Handler对象通过下面的方法执行计划任务:
post(Runnable),提交计划任务马上执行;
postAtTime(Runnable, long),提交计划任务在未来的时间点执行;
postDelayed(Runnable, long),提交计划任务延时Nms执行。
下面我们用代码来实现:
1、使用Message消息
public class HandlerActivity extends AppCompatActivity implements View.OnClickListener { TextView textHandler; Button buttonMessage, buttonRunnable; Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); textHandler = (TextView) findViewById(R.id.text_handler); buttonMessage = (Button) findViewById(R.id.button_message); buttonRunnable = (Button) findViewById(R.id.button_runnable); buttonMessage.setOnClickListener(this); buttonRunnable.setOnClickListener(this); handler = new MyHandler(); } public class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: Log.e("测试", String.valueOf(msg.arg1 + msg.arg2)); textHandler.setText(msg.obj.toString()); break; } } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_message: //使用Message的方式传递消息 new Thread(new Runnable() { @Override public void run() { Message message = handler.obtainMessage(); message.arg1 = 1; message.arg2 = 2; message.obj = "小米"; message.what = 1; message.sendToTarget();// 也可以使用这种方式发送message// handler.sendMessage(message); } }).start(); break; case R.id.button_runnable: //使用Runnable的方式传递消息 new Thread(new Runnable() { @Override public void run() { handler.post(new Runnable() { @Override public void run() { //这句话其实是在创建handler的线程中执行的,这是则是在主线程中运行的 //说明只是把runnable里的run方法放到UI线程里运行,并不会创建新线程 //因此我们可以在子线程中将runnable加入到主线程的MessageQueue,然后主线程将调用runnable的方法,可以在此方法中更新主线程UI。 textHandler.setText("小米2"); } }); } }).start(); break; } }}
2、使用Runnable传递
写在上面代码中!
四、在线程中创建Handler传递消息,还有HandlerThread的使用
如何在线程当中实例化Handler。在线程中实例化Handler我们需要保证线程当中包含Looper(注意:UI-Thread默认包含Looper)。
为线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。
我们实现Looper有没有更加简单的方法呢?当然有,这就是我们的HandlerThread。我们来看下Android对HandlerThread的描述:
—Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
Handler机制的分发中心就在Looper中的loop(),HandlerThread将loop转到子线程中处理,降低了主线程的压力,使主界面更流畅,其实 说白了,创建HandlerThread,只是为了用此线程的looper 最终的runnable都还是post到主线程运行(已用Toast测试过)
使用步骤
尽管HandlerThread的文档比较简单,但是它的使用并没有想象的那么easy。
1、创建一个HandlerThread,即创建了一个包含Looper的线程。
HandlerThread handlerThread = new HandlerThread(“HandlerThread”);
handlerThread.start(); //创建HandlerThread后一定要记得start()
2、获取HandlerThread的Looper
Looper looper = handlerThread.getLooper();
3、创建Handler,通过Looper初始化
Handler handler = new Handler(looper);
通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。
如果想让HandlerThread退出,则需要调用handlerThread.quit();
public class HandlerActivity extends AppCompatActivity implements View.OnClickListener { Button threadHandler, handlerThread; Handler threadHanlder; Handler hanlderThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); threadHandler = (Button) findViewById(R.id.button_thread_handler); handlerThread = (Button) findViewById(R.id.button_handlerthread); threadHandler.setOnClickListener(this); handlerThread.setOnClickListener(this); //使用子线程中创建Handler ThreadHandler threadHandler = new ThreadHandler(); threadHandler.start(); //创建HandlerThread HandlerThread handlerThread = new HandlerThread("hanlderThread"); handlerThread.start(); hanlderThread = new Handler(handlerThread.getLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 2: Log.e("HandlerThread", Thread.currentThread().toString()); break; } } }; Log.e("MianThread", Thread.currentThread().toString()); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_thread_handler: threadHanlder.sendEmptyMessage(1); break; case R.id.button_handlerthread: hanlderThread.sendEmptyMessage(2); break; } } //使用子线程实现Hanlder public class ThreadHandler extends Thread { @Override public void run() { super.run(); Looper.prepare(); threadHanlder = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: Log.e("ThreadHandler", Thread.currentThread().toString()); break; } } }; Looper.loop(); } }}
布局:
- Handler机制的理解与使用
- Handler机制的理解
- Android中Handler的使用与理解
- Handler 消息传递机制的理解与学习
- Handler机制的一些理解
- Handler机制的初步理解
- Handler机制-----我的理解
- Android 中Handler机制的详解与使用
- 对Handler消息机制的理解
- Android Handler消息机制的理解
- 关于handler机制的部分理解
- Android中Handler机制的理解
- Android Handler消息机制的理解
- Android<我所理解的Handler机制>
- 对android Handler机制的理解
- 【Android机制】-- Handler运行机制的理解
- Android<我所理解的Handler机制>
- 对Handler机制的”粗“理解
- ViewPager的基本使用
- You are installing software that contain unsigned content and authenticity and validity of this soft
- [转]Golang中goroutine的调度器详解
- SHM
- android:快速开发插件推荐
- Handler机制的理解与使用
- 网络基本功:UDP/IP与TCP/IP的区别
- 同门腾讯面试遇到的问题
- iOS 去除按钮的按下效果(阴影)
- 【SDOI2015】【BZOJ4086】旅行计划travel
- 利用pycaffe提取caffe model中的参数
- /dev/null: Permission denied
- 强制下线通知-基于应用的系统级别对话框
- Android API Guides---Accessibility