【Android】Android实现Handler异步详解
方式不止一种,这里使用的是Timer类,创建一个定时器。我们经常需要获得移动设备端口的显示屏信息,但是onCreate()方法执行的时候,OnShow()方法不一定执行了,也就是说,在执行Oncreate()时候屏幕还没加载出来,所以这时候可以应用一个异步机制获取数据。
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.view.View; import java.util.Timer;
import java.util.TimerTask; /**
* Created by Lenovo on 2017/6/2.
*/
public abstract class MyActivity extends Activity{
protected abstract void ViewAfterShow(int width,int hight);
/**
* 使用线程异步,获取视图上的数据,比如高和宽
* @param viewID 视图ID
* @param msgID 消息ID
*/
protected void ViewShowListen(final int viewID,final int msgID){
//always make sure that schedule is running from main thread
if(Looper.getMainLooper() == Looper.myLooper())
runTimeSchedule(viewID,msgID);
else
new Handler(getMainLooper()).post(new Runnable() {
@Override
public void run() {
runTimeSchedule(viewID,msgID);
}
}); }
public void runTimeSchedule(final int viewID,final int msgID){
final int f_viewID = viewID;
final int f_msgID = msgID;
final Timer f_timer = new Timer();
final Handler f_handler = new Handler(){
@Override
public void handleMessage(Message msg){
if(msg.what == f_msgID){
View v = (View)findViewById(f_viewID);
if(v.getWidth() != 0 && v.getHeight() != 0){
f_timer.cancel();//取消
ViewAfterShow(v.getWidth(),v.getHeight());//回调信息
}
}
}
};
//这里之所以不在该run()方法里进行操作,是因为里面的数据是最终的,所以这里应用了一个消息发送机制。
TimerTask task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = f_msgID;
f_handler.sendMessage(message);//发送消息
}
};
//延迟每次延迟10毫秒 隔500毫秒执行一次
f_timer.schedule(task,10,500);
}
}
上面是关于TimerTask和Handler的一种用法,上面调用的是Handler的 sendMessage(Message msg) ,除了sendMessage方法,还有 handleMessage(Message msg) 方法,注意handleMessage方法和sendMessage方法的效果是不一样的,sendMessage是handler在主线程中执行;但是handlerMessage则不会,所处理的Handler还是在Timer线程中。
下面详细介绍一下TimerTask类和Handler类,TimerTask中创建的线程是一个单独的线程,命名通常以 timer+数字 表示,一帮数字从0开始。而Hanler不会创建新的线程,如果不使用Looper标识,那么Handler处于的线程将会是在main(主)线程中,比如:
public class MainActivity extends Activity {
Context context;
LinearLayout layout;
int f_msgID = 2;
final Timer f_timer = new Timer();
final Handler f_handler = new Handler(){
@Override
public void handleMessage(Message msg){
if(msg.what == f_msgID){
Log.e("d", Thread.currentThread().getName());//main
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=this;
layout=(LinearLayout)findViewById(R.id.mainlayout);
Log.e("a",Thread.currentThread().getName());//main
new Thread(new Runnable() {
@Override
public void run() {
Log.e("b", Thread.currentThread().getName());//thread-11840
TimerTask task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = f_msgID;
f_handler.sendMessage(message);
Log.e("c", Thread.currentThread().getName());//timer-0
}
};
f_timer.schedule(task,10,10000);
}
}).start();
}
}
笔者在上面的代码上中,标识出了各个线程中运行的线程名称,一共有三个线程,可以发现Handler所处的线程是在主线程中的。
接下来如果是使用Looper的话,Handler所处的线程为Looper所处的线程,比如:
public class MainActivity extends Activity {
Context context;
LinearLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
layout = (LinearLayout) findViewById(R.id.mainlayout);
Log.e("a", Thread.currentThread().getName());// main
new Thread(new Runnable() {
@Override
public void run() {
Log.e("b", Thread.currentThread().getName());// thread-11899
final int f_msgID = 2;
Looper.prepare();// looper begin
final Timer f_timer = new Timer();
final Handler f_handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == f_msgID) {
Log.e("c", Thread.currentThread().getName());//thread-11899
}
}
};
TimerTask task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = f_msgID;
f_handler.sendMessage(message);
Log.e("d", Thread.currentThread().getName());// timer-0
}
};
f_timer.schedule(task, 10, 10000);
Looper.loop();// looper end
}
}).start();
}
}
从这个过程中我们可以看出,Handler和 Log.e("b", Thread.currentThread().getName()) 所处的线程都在Thread-11899中,这个线程编号是程序自动指定的。
上面我们介绍这个Handler和TimerTask的比较。视图组件有一个特性,就是修改该组件只能在创建该组件的原始线程中完成,如果创建的视图组件的线程和修改视图组件的线程不在同一个线程中,那么就会报错。而有时候,我们又希望在非创建组件的线程中修改组件,那么这时候,就可以应用上的特性。
【Android】Android实现Handler异步详解的更多相关文章
- Android App优化之ANR详解
引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...
- Android Telephony分析(三) ---- RILJ详解
前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)
. 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...
- Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!
Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解
. 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...
- Android Telephony分析(五) ---- TelephonyRegistry详解
本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...
- Android Telephony分析(二) ---- RegistrantList详解
前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Android图片缓存之Bitmap详解
前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...
随机推荐
- Android Handler 消息处理使用
本文内容 环境 演示 Handler 消息处理 参考资料 Handler 有两个主要作用或者说是步骤:发送消息和处理消息.在新启动的线程中发送消息,在主线程中获取.并处理消息.Android 平台只允 ...
- Android缓存处理
Android缓存: 採用缓存,能够进一步大大缓解数据交互的压力,又能提供一定的离线浏览.下边我简略列举一下缓存管理的适用环境: 1. 提供网络服务的应用 2. 数据更新不须要实时更新.哪怕是3-5分 ...
- Fibre Channel address weaknesses
http://searchitchannel.techtarget.com/feature/Fibre-Channel-address-weaknesses Figure 2.1 Five layer ...
- stingray 页面布局与设计
前言 前面我们已经了解了系统中的HTML组件,现在我们就可以开始用这些组件来设计页面了,他们就像是一块块小积木,我们要盖起高楼大厦. 两种页面容器组件 我们将关联性较强的多个HTML组件放到一个容器组 ...
- python environ PYTHON_EGG_CACHE
My first thought was "Wow, that's quite a long way of telling me to 'just quit.'" Not want ...
- Laravel中pluck的使用——返回指定的字段值信息列表
$model = self::where(['is_delete' => 0, 'is_on_sale' => 1]) ->whereIn('goods.cat_id', Goods ...
- java 八种基本数据类型之与对应的封装类之间的相互转化
迁移时间--2017年5月26日17:47:37 Author:Marydon 一.java数据类型之基本数据类型 UpdateTime--2017年1月9日17:31:14 (三)格式转换 1. ...
- How to get the value of a form element : check box and radio button
Getting a radio element and it’s checked value Radio buttons in a form can be grouped together using ...
- Leveldb 使用说明文档
Leveldb 使用说明文档 原作者:Jeff Dean, Sanjay Ghemawat 翻译:乌合之众solym@sohu.com 英文原文地址https://rawgit.com/google/ ...
- redis配置笔记
#cd /opt#tar -zxvf redis-4.0.6.tar.gz#cd redis-4.0.6#make #cd src#make install PREFIX=/usr/local/red ...