android之handler使用与原理
来源:互联网 发布:简述网络安全技术 编辑:程序博客网 时间:2024/06/13 15:17
下面的是个人对handler的一些感想,忘能帮助初学者
handler是什么
handler是android系统提供的一套消息机制的上层接口,使用handler可以轻松地切换任务线程那它可以用来干嘛呢。
当需要在子线程中进行耗时的I/O操作的时候,当耗时任务完成以后,需要在UI上做一些改变,但是在子线程不能访问handler这时就要使用handler。要记住一点,handler不是专门用来更新UI的。
接下来介绍几个概念。
MessageQueue
它是用来存储消息的,注意它是单链表的数据结构。
Looper
消息循环者,用来取MessageQueue的消息并处理,没消息阻塞。
好了,接下来慢慢介绍。
不知大家注意到了没子线程访问UI会报异常,这是因为不能再子线程更新UI,那么android是怎么确定的呢,因为ViewRootImpl会对UI操作进行验证,是由ViewRootImpl的checkThread来完成的。因此大家也别想着用什么办法绕过了,因为系统已经强制规定了。
Handler在创建的时候会用当前线程的Looper来构建消息循环系统,因此在子线程中直接使用Handler会报错,因为子线程是没有Looper的,那UI线程有没有呢,UI线程会在ActivityThread创建UI线程的时候初始化一个Looper,这也是主线程可以使用handler的原因,要在子线程使用handler,要先出初始化Looper,调用Looper.perpar()即可当调用handler的send方法时,它会调用MessageQueue的enqueueMessage()方法将消息放到队列中去,Looper发现有新消息时会处理消息,最终消息中的Runnable或者handler的handleMessage会调用。
这里要知道Looper是存储在ThreadLocal中的,它是一个作用域为当前线程的存储类。底下是个例子
public class TestHandlerActivity extends AppCompatActivity { private static final String TAG = "TestHandlerActivity"; private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //获得刚才发送的Message对象,然后在这里进行UI操作 Log.e(TAG,"------------> msg.what = " + msg.what); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler_test); initData(); } private void initData() { //开启一个线程模拟处理耗时的操作 new Thread(new Runnable() { @Override public void run() { SystemClock.sleep(2000); //通过Handler发送一个消息切换回主线程(mHandler所在的线程) mHandler.sendEmptyMessage(0); } }).start(); }
这是一个很简单的例子,接下来再看用post方法发送已个Runnable接口的方法。
public class MainActivity extends Activity { private TextView text_view = null; private Button start = null; private Button end = null; //使用handler时首先要创建一个handler Handler handler = new Handler(); //要用handler来处理多线程可以使用runnable接口,这里先定义该接口 //线程中运行该接口的run函数 Runnable update_thread = new Runnable() { public void run() { //线程每次执行时输出"UpdateThread..."文字,且自动换行 //textview的append功能和Qt中的append类似,不会覆盖前面 //的内容,只是Qt中的append默认是自动换行模式 text_view.append("\nUpdateThread..."); //延时1s后又将线程加入到线程队列中 handler.postDelayed(update_thread, 1000); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text_view = (TextView)findViewById(R.id.text_view); start = (Button)findViewById(R.id.start); start.setOnClickListener(new StartClickListener()); end = (Button)findViewById(R.id.end); end.setOnClickListener(new EndClickListener()); } private class StartClickListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub //将线程接口立刻送到线程队列中 handler.post(update_thread); } } private class EndClickListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub //将接口从线程队列中移除 handler.removeCallbacks(update_thread); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }}
接下来各自分析一下
MessageQueue
它主要用来存储消息,有两个基本操作,插入和读取,读取操作会伴随着删除操作,当Handler发送一条消息时会调用他的enqueueMessage方法插入消息,此时有了一条消息,接着它会调用自身的next方法读取消息并从队列中(数据结构是单链表)删除消息,接着Looper发现有消息就会把它交给handler去处理,handler调用自身的handlermessage()方法,这里要注意我们可以通过getMainLooper()得到UI现成的Looper,当在子线程创建Looper不用的时候要调用他的quitsafely()方法,否则Looper会一直阻塞。
好了,这就是消息处理机制了。
- android之handler使用与原理
- Handler的使用与原理
- Android之handler使用
- android之handler使用
- android之handler使用
- Android 之 Handler 使用
- Android之Handler与线程
- Android之Handler与线程
- Android之Handler与线程
- Android之Handler与多线程
- Android开发技术-Handler机制与原理
- Android Handler与Looper原理浅析
- Android基础篇之Handler实现原理
- Android之Handler原理回顾和剖析
- Android之handler的使用
- Android 线程之Handler使用
- android之Handler的使用
- Android基础之Handler使用
- MySQL中myisam和innodb的主键索引有什么区别?
- Python之print函数详解
- 【Python3 笔记】基础语法
- WIN7系统问题解决记录
- Runnable接口
- android之handler使用与原理
- 慕课 springmvc 起步 maven wbe
- 【程序】STM32F103单片机使用定时器DMA进行全自动8位数码管动态扫描
- 动态规划法(一)——概述
- jzoj P2016 最小步数
- mqtt实现库对比
- 使用IntelliJ IDEA 14和Maven创建java web项目
- 完美解决textarea输入框提示文字,必须添加默认内容
- 公司服务器中了病毒,用了命令查找最近100天的可执行文件,找出病毒文件,并删除