好玩的Handler
- Android提供了Handler和Looper来满足线程间的通信;
- Handler和Activity的任务栈不同,它是先进先出原则;
- Handler:你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里,或者接口Looper从MessageQueue取出的消息;
- Looper类用来管理特定线程内对象之间交换Message;
- 一个线程可以产生一个Looper对象,由他来管理此线程的MessageQueue(消息队列);
- MessageQueue:用来存放线程放入的消息;
- 每一个消息都需要制定的Handler来处理,通过Handler创建消息便可以完成此功能.Android引入了消息池.Handler创建消息时首先查询消息池中是否有消息存在,如果有,则直接取出,如果没有,则重新初始化一个消息实例.
- 使用消息池的好处是:消息不被使用时,并不作为垃圾回收,而是放入消息池中,可供下次Handler创建消息时使用.消息池提高了消息对象的复用,减少系统垃圾回收的次数.Message.obtain()来获取消息,最大数为50;
- 综上所述:这就是一个标准的的异步操作,就像我们寄信一样,我们只负责写好信(Message)通过邮递员(Handler)放入到邮箱(MessageQueue)中,由工作人员(Looper)去循环查询,再由邮递员处理(Handler)处理这些消息;
- 应用场景:两秒后打开一个Activity
- //延迟两秒跳转
newHandler().postDelayed(newRunnable(){
@Override
publicvoid run(){
Intent intent=newIntent(MainActivity.this,TestActivity.class);
startActivity(intent);
}
},2000);
- 先来看一个简单的消息吧
- privateProgressBar mProgressBar;
privateint i =0;
privateHandler mHandler =newHandler(){ // 创建Handle
@Override
publicvoid handleMessage(Message msg){
super.handleMessage(msg);
Log.i("-mHandler->",i+"");
mProgressBar.setProgress(i);
}
};
privateRunnable runnable =newRunnable(){
@Override
publicvoid run(){
Log.i("-Runnable->",i+"");
i +=10;
// 要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
mHandler.postDelayed(runnable,2000); // 定时器
mHandler.sendMessageDelayed(Message.obtain(),0);// 发送消息才会触发重写的handleMessage方法
}
};
@Override
protectedvoid onCreate(@NullableBundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
mProgressBar =(ProgressBar) findViewById(R.id.pb_handler);
mHandler.post(runnable);// 开始执行线程
// runnable.run(); // 也可以用这个来开始线程
}
/**
* 删除的时候停止线程操作
*/
@Override
protectedvoid onDestroy(){
super.onDestroy();
mHandler.removeCallbacks(runnable);
}
}
- 获取Message的两种方法
- // 两种获取Message的方法
// Returns a new Message from the global message pool.
mHandler.obtainMessage()和Message.obtain()
- // 两种方法其实是一样的,只不过一个是通过Handler获取,一个是通过Message的静态方法获得,查询Handler的源码会发现,obtainMessage的方法构成:
publicfinalMessage obtainMessage()
{
returnMessage.obtain(this);
}
- 通过查询源码后发现,Message提供了诸如以下的变量
- Message的recycleUnchecked()方法
void recycleUnchecked(){
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags = FLAG_IN_USE; //int
what =0; // int
arg1 =0; // int
arg2 =0; // int
obj =null; // Object
replyTo =null; // Messenger 信使,信差
sendingUid =-1;
when =0; // long
target =null; // Handler
callback =null; // Runable
data =null; // Bundle
synchronized(sPoolSync){
if(sPoolSize < MAX_POOL_SIZE){
next = sPool;
sPool =this;
sPoolSize++;
}
}
}
使用系统变量的好处是可以大大减少系统的消耗;所以更新进度条的代码应修改为mProgressBar.setProgress(msg.arg1);
- privateRunnable runnable =newRunnable(){
@Override
publicvoid run(){
Log.i("-Runnable->", i +"");
i +=3;
// 要做的事情,这里再次调用此Runnable对象,以实现每两秒实现一次的定时器操作
mHandler.postDelayed(runnable,300);
Message msg = mHandler.obtainMessage();
msg.arg1 +=i;
mHandler.sendMessage(msg);// 发送消息才会触发重写的handleMessage方法
// mHandler.sendMessageDelayed(Message.obtain(),0); // 发送消息才会触发重写的handleMessage方法
}
};
- 重新优化下Handler
- privateHandler mHandler =newHandler(){
@Override
publicvoid handleMessage(Message msg){
super.handleMessage(msg);
//Log.i("-mHandler->", i + "");
if(msg.arg1 >100){
mHandler.removeCallbacks(runnable);
}else{
mProgressBar.setProgress(msg.arg1);
}
}
};
好玩的Handler的更多相关文章
- android Handler介绍
Handler使用介绍: Handler根据接收的消息,处理UI更新.Thread线程发出消息,通知Handler更新UI. Handler mHandler = new Handler() { p ...
- Handler
1.1 继承AbstractController优点:能定制请求方式 package cn.happyl.controller; import javax.servlet.http.HttpServl ...
- Android消息处理机制(Handler、Looper、MessageQueue与Message)
Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...
- Android笔记——Handler Runnable与Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- Android消息传递之Handler消息机制
前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...
- Handler系列之内存泄漏
本篇简单的讲一下平常使用Handler时造成内存泄漏的问题. 什么是内存泄漏?大白话讲就是分配出去的内存,回收不回来.严重会导致内存不足OOM.下面来看一下造成内存泄漏的代码: public clas ...
- Handler系列之创建子线程Handler
上一篇我介绍了Handler机制的工作原理,默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handl ...
- Handler系列之原理分析
上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...
- Handler系列之使用
作为一个Android开发者,我们肯定熟悉并使用过Handler机制.最常用的使用场景是"在子线程更新ui",实际上我们知道上面的说话是错误的.因为Android中只有主线程才能更 ...
随机推荐
- 搭建TFS 2015 Build Agent环境(一)
Download the build agent Downloading the build agent is really simple. Navigate to your TFS control ...
- .NET Web的身份认证
百度一下”asp.net身份认证“,你会得到很多相关的资料,这些资料通常上来就会介绍诸如”Form认证“”Windows认证“等内容,而没有给出一个完整的流程.初学者对此往往一头雾水,我也曾经被坑过很 ...
- Leetcode 笔记 113 - Path Sum II
题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...
- 用Go语言做产品半年的一些感觉
用Go语言做产品刚好半年,有一些感觉跟大家说道说道. 在使用Go之前,我常常想象,无法使用先进的Debug工具会对工作进度造成多么巨大的影响.甚至在Visual Studio的娇惯下认为,不能调试基本 ...
- AngularJs之三
一.angularJs的指令模型ng-model指令 ng-model 指令 绑定 HTML 元素 到应用程序数据. 为应用程序数据提供类型验证(number.email.required).为应用程 ...
- thinkphp - 复合查询(or、and 联合使用的方法)
条件:查询今天内邮箱和QQ其中一项都不为空的有效数据的查询 释义:(or 条件)email 不为空 或者 qq_no 不为空 (and 条件) is_deleted 为0 并且 create_ ...
- Python初学者之网络爬虫(二)
声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途.转载请附上此文章地址 本篇文章Python初学者之网络爬虫的继续,最新代码已提交到https://github.com/octans ...
- Enterprise Solution 生成实体数据访问接口与实现类型 Code Smith 6.5 模板文件下载
数据库表定义为SalesOrder,用LLBL Gen Pro生成的实体定义是SalesOrderEntity,再用Code Smith生成的数据读写接口是ISalesOrderManager,最后是 ...
- 初识 Sql Server存储过程
开篇语 之前的公司并未使用存储过程来做项目,所以小生对存储过程的调用.使用也是一知半解,刚好这家公司就大量用到了存储过程 这次做的功能,为了保持风格一致,也是需要使用存储过程来实现动态sql和数据分页 ...
- 1. 使用Filter 作为控制器
最近整理一下学习笔记,并且准备放到自己的博客上.也顺便把Struts2 复习一遍 1. MVC 设计模式概览 实现 MVC(Model.View.Controller) 模式的应用程序由 3 大部分构 ...