方式不止一种,这里使用的是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. capwap学习笔记——初识capwap(一)

    2 初识CAPWAP 2.1 CAPWAP简介 说了半天CAPWAP,连全称都还没说,汗-- CAPWAP--Control And Provisioning of Wireless Access P ...

  2. pycharm+python+Django之web开发环境的搭建(windows)

    转载:https://blog.csdn.net/yjx2323999451/article/details/53200243/ pycharm+python+Django之web开发环境的搭建(wi ...

  3. window.btoa

    概述 将ascii字符串或二进制数据转换成一个base64编码过的字符串,该方法不能直接作用于Unicode字符串. 语法 var encodedData = window.btoa(stringTo ...

  4. 【POJ 3071】 Football(DP)

    [POJ 3071] Football(DP) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4350   Accepted ...

  5. IDEA引入外部jar包的方法

    在做发短信的功能(阿里大于)的时候,我只是吧jar包拷贝到了项目的external library. 拷贝进来之后我用junit写了test方法,可以完美发送短信到手机,但是我这是个web项目,然后我 ...

  6. updateFilter

    $.fn.updateFilter = function(filterType, paramVal) { // filter="DATE|GREATERTHANEQUALS|LESSTHAN ...

  7. hibernate5(12)注解映射[4]一对一外键关联

    在实际博客站点中,文章内容的数据量非常多,它会影响我们检索文章其他数据的时间,如查询公布时间.标题.类别的等. 这个时候,我们能够尝试将文章内容存在还有一张表中,然后建立起文章--文章内容的一对一映射 ...

  8. SqlDataAdapter概述

    SqlDataAdapter是 DataSet和 SQL Server之间的桥接器,用于检索和保存数据.SqlDataAdapter通过对数据源使用适当的Transact-SQL语句映射 Fill(它 ...

  9. cocos2d-js 3.0 屏幕适配方案 分辨率适应

    首先介绍一个api和相应的参数: cc.view.setDesignResolutionSize(1024, 768, cc.ResolutionPolicy.FIXED_WIDTH); 这里设置游戏 ...

  10. Web Service 简介

    最近使用ODI的工具箱中的ODIInvokeWebService.因此简单了解下WebService的理论知识. 一.Web Service 简介 Web Service就是可编程的URL,使用标准的 ...