方式不止一种,这里使用的是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异步详解的更多相关文章

  1. Android App优化之ANR详解

    引言 背景:Android App优化, 要怎么做? Android App优化之性能分析工具 Android App优化之提升你的App启动速度之理论基础 Android App优化之提升你的App ...

  2. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...

  3. 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)

    . 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...

  4. Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!

    Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...

  5. 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解

    . 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...

  6. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...

  7. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...

  8. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  9. Android图片缓存之Bitmap详解

    前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...

随机推荐

  1. 文字编码和Unicode

    文字编码和Unicode 说明文字: https://blog.csdn.net/fengzhishang2019/article/details/7859064 Java 程序: https://w ...

  2. 复习C语言:第一章

    复习C语言中的5中基本类型,以及各个类型占用了多少个字节: #include <stdio.h> int main(void) { printf("int=%d\n", ...

  3. 两种解决IE6不支持固定定位的方法

    有两种让IE6支持position:fixed1.用CSS执行表达式 *{margin:0;padding:0;} * html,* html body{ background-image:url(a ...

  4. 自定义控件之万能Repeater源码

    using System.ComponentModel; using System.Web.UI; [assembly: TagPrefix("Jinlong.Control", ...

  5. css规范 - bem

    用我的话简述来说,即 B:何种元素 E:何种模块使用它(header,footer)等 M:描述它是做何种事情的 例如就是我有个主页,名称是:index.html index_header_logo ...

  6. Linux下验证码无法显示,Could not initialize class sun.awt.X1 解决方案

    环境:Oracle Linux 6.4,JDK1.6,Weblogic11g 在通过java.awt生成图片验证码时,提示: Could not initialize class sun.awt.X1 ...

  7. MySQL:Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT...

    1:错误日志大量错误 150602 14:40:02 [Warning] Unsafe statement written to the binary log using statement form ...

  8. Sql server中依据存储过程中的部分信息查找存储过程名称的方法【视图和Function】

    1.查询的语句: select a.id,b.name,a.*,b.* from syscomments a join sysobjects b on a.id=b.id where b.xtype= ...

  9. jqPlot图表插件学习之柱形图和旋转分类名称

    一.准备工作 首先我们需要到官网下载所需的文件: 官网下载(笔者选择的是jquery.jqplot.1.0.8r1250.zip这个版本) 然后读者需要根据自己的情况新建一个项目并且按照如下的方式加载 ...

  10. 粒子滤波跟踪移动机器人(MATLAB Robotics System Toolbox)

    MathWorks从MATLAB 2015a开始推出与ROS集成的Robotics System Toolbox(机器人系统工具箱),它为自主移动机器人的研发提供现成的算法和硬件接口. 粒子滤波基本流 ...