方法一:(java习惯,在android平台开发时这样是不行的,因为它违背了单线程模型)

刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题

new Thread( new Runnable() {     
publicvoid run() {
myView.invalidate();
}
}).start();

可以实现功能,刷新UI界面。但是这样是不行的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

方法二:(Thread+Handler)

查阅了文档和apidemo后,发觉常用的方法是利用Handler来实现UI线程的更新的。

Handler来根据接收的消息,处理UI更新。Thread线程发出Handler消息,通知更新UI。

Handler myHandler = new Handler() {  
public void handleMessage(Message msg) {
switch (msg.what) {
case TestHandler.GUIUPDATEIDENTIFIER:
myBounceView.invalidate();
break;
}
super.handleMessage(msg);
}
};
class myThread implements Runnable {   
publicvoid run() {
while (!Thread.currentThread().isInterrupted()) { Message message = new Message();
message.what = TestHandler.GUIUPDATEIDENTIFIER; TestHandler.this.myHandler.sendMessage(message);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

以上方法demo看:http://rayleung.javaeye.com/blog/411860

方法三:(java习惯。Android平台中,这样做是不行的,这跟Android的线程安全有关)

在Android平台中需要反复按周期执行方法可以使用Java上自带的TimerTask类,TimerTask相对于Thread来说对于资源 消耗的更低,除了使用Android自带的AlarmManager,使用Timer定时器是一种更好的解决方法。 我们需要引入import java.util.Timer; 和 import java.util.TimerTask;

publicclass JavaTimer extends Activity {  

    Timer timer = new Timer();  
TimerTask task = new TimerTask(){
publicvoid run() {
setTitle("hear me?");
}
}; publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); timer.schedule(task, 10000); }
}

方法四:(TimerTask + Handler)

通过配合Handler来实现timer功能的!

publicclass TestTimer extends Activity {  

    Timer timer = new Timer();  
Handler handler = new Handler(){
publicvoid handleMessage(Message msg) {
switch (msg.what) {
case 1:
setTitle("hear me?");
break;
}
super.handleMessage(msg);
}
}; TimerTask task = new TimerTask(){
publicvoid run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}; publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); timer.schedule(task, 10000);
}
}

方法五:( Runnable + Handler.postDelayed(runnable,time) )

在Android里定时更新 UI,通常使用的是 java.util.Timerjava.util.TimerTask, android.os.Handler组合。实际上Handler 自身已经提供了定时的功能。

private Handler handler = new Handler();  

private Runnable myRunnable= new Runnable() {    
publicvoid run() { if (run) {
handler.postDelayed(this, 1000);
count++;
}
tvCounter.setText("Count: " + count); }
};

然后在其他地方调用

handler.post(myRunnable);

handler.post(myRunnable,time);

案例看:http://shaobin0604.javaeye.com/blog/515820

====================================================================

知识点总结补充:

很多初入Android或Java开发的新手对Thread、Looper、Handler和Message仍然比较迷惑,衍生的有 HandlerThread、java.util.concurrent、Task、AsyncTask由于目前市面上的书籍等资料都没有谈到这些问题, 今天就这一问题做更系统性的总结。我们创建的Service、Activity以及Broadcast均是一个主线程处理,这里我们可以理解为UI线程。但是在操作一些耗时操作时,比如I/O读写的大文件读写,数据库操作以及网络下载需要很长时间,为了不阻塞用户界面,出现ANR的响应提示窗口,这个时候我们可以考虑使用Thread线程来解决。

对于从事过J2ME开发的程序员来说Thread比较简单,直接匿名创建重写run方法,调用start方法执行即可。或者从Runnable接口继承,但对于Android平台来说UI控件都没有设计成为线程安全类型,所以需要引入一些同步的机制来使其刷新,这点Google在设计Android时倒是参考了下Win32的消息处理机制。

1. 对于线程中的刷新一个View为基类的界面,可以使用postInvalidate()方法在 线程中来处理,其中还提供了一些重写方法比如postInvalidate(int left,int top,int right,int bottom) 来刷新一个矩形区域,以及延时执行,比如postInvalidateDelayed(long delayMilliseconds)或postInvalidateDelayed(long delayMilliseconds,int left,int top,int right,int bottom) 方法,其中第一个参数为毫秒

2. 当然推荐的方法是通过一个Handler来处理这些,可以在一个线程的 run方法中调用handler对象的 postMessage或sendMessage方法来实现,Android程序内部维护着一个消息队列,会轮询处理这些,如果你是Win32程序员可以 很好理解这些消息处理,不过相对于Android来说没有提供 PreTranslateMessage这些干涉内部的方法。

3. Looper又是什么呢? ,其实Android中每一个Thread都跟着一个Looper,Looper可以帮助Thread维护一个消息队列,但是Looper和 Handler没有什么关系,我们从开源的代码可以看到Android还提供了一个Thread继承类HanderThread可以帮助我们处理,在 HandlerThread对象中可以通过getLooper方法获取一个Looper对象控制句柄,我们可以将其这个Looper对象映射到一个 Handler中去来实现一个线程同步机制,Looper对象的执行需要初始化Looper.prepare方法就是昨天我们看到的问题,同时推出时还要 释放资源,使用Looper.release方法。

4.Message 在Android是什么呢? 对于Android中Handler可以传递一些内容,通过Bundle对象可以封装String、Integer以及Blob二进制对象,我们通过在线程中使用Handler对象的sendEmptyMessage或sendMessage方法来传递一个Bundle对象到Handler处理器。对于Handler类提供了重写方法handleMessage(Message msg) 来判断,通过msg.what来区分每条信息。 将Bundle解包来实现Handler类更新UI线程中的内容实现控件的刷新操作。相关的Handler对象有关消息发送sendXXXX相关方法如 下,同时还有postXXXX相关方法,这些和Win32中的道理基本一致,一个为发送后直接返回,一个为处理后才返回 .

5. java.util.concurrent对象分析,对于过去从事Java开发的程序员不会对Concurrent对象感到陌生吧,他是JDK 1.5以后新增的重要特性作为掌上设备,我们不提倡使用该类,考虑到Android为我们已经设计好的Task机制,这里不做过多的赘述,相关原因参考下 面的介绍:

6. 在Android中还提供了一种有别于线程的处理方式,就是Task以及AsyncTask,从开源代码中可以看到是针对Concurrent的封装,开发人员可以方便的处理这些异步任务。

摘录自:http://www.cnblogs.com/playing/archive/2011/03/24/1993583.html

Handler使用总结(转)的更多相关文章

  1. android Handler介绍

    Handler使用介绍: Handler根据接收的消息,处理UI更新.Thread线程发出消息,通知Handler更新UI. Handler mHandler = new Handler() {  p ...

  2. Handler

    1.1 继承AbstractController优点:能定制请求方式 package cn.happyl.controller; import javax.servlet.http.HttpServl ...

  3. Android消息处理机制(Handler、Looper、MessageQueue与Message)

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  4. Android笔记——Handler Runnable与Thread的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  5. Android消息传递之Handler消息机制

    前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...

  6. Handler系列之内存泄漏

    本篇简单的讲一下平常使用Handler时造成内存泄漏的问题. 什么是内存泄漏?大白话讲就是分配出去的内存,回收不回来.严重会导致内存不足OOM.下面来看一下造成内存泄漏的代码: public clas ...

  7. Handler系列之创建子线程Handler

    上一篇我介绍了Handler机制的工作原理,默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handl ...

  8. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  9. Handler系列之使用

    作为一个Android开发者,我们肯定熟悉并使用过Handler机制.最常用的使用场景是"在子线程更新ui",实际上我们知道上面的说话是错误的.因为Android中只有主线程才能更 ...

  10. 阶段一:用Handler和Message实现计时效果及其中一些疑问

    “阶段一”是指我第一次系统地学习Android开发.这主要是对我的学习过程作个记录. 本来是打算继续做天气预报的优化的,但因为某些原因,我要先把之前做的小应用优化一下.所以今天就插播一下用Handle ...

随机推荐

  1. onethink上传图片(资源)和预览

    直接上干货 不废话了 普通上传:  onthink框架 后台已经有图片和文件上传功能 controller里只需: public function addPicture(){ /* 调用文件上传组件上 ...

  2. ios 自定义键盘

    由于项目需要,需要自定义键盘.ios系统键盘会缓存键盘输入,并保存在系统目录下的文件里,并且是明文存储,存在帐号密码泄漏风险.在别人代码基础上修改了下,美化了下界面,去掉了字符输入,加了点击特效,截图 ...

  3. 《开源安全运维平台OSSIM最佳实践》

    <开源安全运维平台OSSIM最佳实践> 经多年潜心研究开源技术,历时三年创作的<开源安全运维平台OSSIM最佳实践>一书即将出版.该书用80多万字记录了,作者10多年的IT行业 ...

  4. 软件调试——IA-32 保护模式下寄存器一览

    最近在看张银奎先生的<调试软件>一书,想将关键的技术记录下来,以便日后查阅,也分享给想看之人吧. 1 通用寄存器 EAX,EBX,ECX,EDX:用于运算的通用寄存器,可以使用AX,BX等 ...

  5. jquery一些基本函数

    jquery.com1.x版本兼容ie2.x版本简化适合移动端 $('li:first') 第一个$('li:eq(2)') $('li:last') 最后一个$('li:odd') 偶数行 1 3$ ...

  6. 4、C#进阶:MD5加密、进程、线程、GDI+、XML、委托

    MD5加密 将字符串进行加密,无法解密.网上的解密方式也都是在库里找,找不到也没有. 1 protected void Page_Load(object sender, EventArgs e) 2 ...

  7. java网络流传输,中文乱码问题。

    最近需要从某个网页上抓取数据.一波三折. 1. 先要找到网站页面调用后台数据服务的url地址,但是本人对js不了解,花了不少时间在分析其网页源代码的js部分,试图寻找出调用数据的链接. 后来得知浏览器 ...

  8. 控制input框不能更改里面的内容

    <input type="text" disabled="true"/> 这个是给input设置一个属性.控制它可以不能改变里面的内容.已经试过了! ...

  9. Quartz.NET作业调度框架详解(转)

    Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中.它提供了巨大的灵活性而不牺牲 ...

  10. LB负载均衡层次结构(摘抄)

    作为后端应用的开发者,我们经常开发.调试.测试完我们的应用并发布到生产环境,用户就可以直接访问到我们的应用了.但对于互联网应用,在你的应用和用户之间还隔着一层低调的或厚或薄的负载均衡层软件,它们不显山 ...