方式不止一种,这里使用的是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. Java归去来第3集:Eclipse中给动态模块升级

    一.前言 如果还不了解剧情,请返回第2集的剧情          Java归去来第2集:利用Eclipse创建Maven Web项目 二.开始升级动态模块 2.1:查看原来的版本 我们先来看看Ecli ...

  2. Python爬虫学习系列教程

    最近想学一下Python爬虫与检索相关的知识,在网上看到这个教程,觉得挺不错的,分享给大家. 来源:http://cuiqingcai.com/1052.html 一.Python入门 1. Pyth ...

  3. 【S6】当心C++编译器最烦人的分析机制

    1.考虑一个包含int的文件,复制到list,如下: ifstream dataFile("ints.bat"); list<int> data(istream_ite ...

  4. redis 五种数据结构详解(string,list,set,zset,hash),各种问题综合

    redis 五种数据结构详解(string,list,set,zset,hash) https://www.cnblogs.com/sdgf/p/6244937.html redis 与 spring ...

  5. SpringBoot添加对jsp的支持

    1.在pom.xml添加如下内容: <dependency> <groupId>org.apache.tomcat.embed</groupId> <arti ...

  6. 报错信息:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

    用Eclipse创建jsp页面时,提示这个错误 解决的方法是:右键项目,Build Path->Configure Build Path Add Library Server Runtime,这 ...

  7. 百度搜索URL参数

    http://www.baidu.com/s?wd=关键字wd(Keyword):查询的关键词:http://www.baidu.com/s?wd=关键字&cl=3cl(Class):搜索类型 ...

  8. FIS.js前端开发的使用说明文档

    文档结构 什么是FIS 部署FIS FIS基本使用 模块定义 加载方式 调用Tangram 2.0 一.什么是FIS FIS提供了一套贯穿开发流程的开发体系和集成开发环境,为产品线提供前端开发底层架构 ...

  9. ZH奶酪:Git简明教程

    这里是原网站:https://try.github.io/levels/1/challenges/1 这篇博文就当是笔记+翻译吧. 几个名词相关 changes:变更 repository:仓库 st ...

  10. Selenium2(webdriver)_定位不到元素常见原因及解决办法

    在做web应用的自动化测试时,定位元素是必不可少的,这个过程经常会碰到定位不到元素的情况,一般可以从以下几个方面着手解决: 1.Frame/Iframe原因定位不到元素: 这个是最常见的原因,首先要理 ...