假设这里有同一个Runnable对象r。

可能采用的方法有:

第一种:

handler.post(r);

实际上这种方法并没有调用线程someThread的start方法,而是直接调用了Runaable中的run方法。这里的调用和activity同步,当run运行时acitvity将会被阻塞,如果run中的内容比较耗时,那么对于用户来说activity的呈现就是界面不动,如死机一般,给用户体验相当糟糕,所以得想办法改进。

第二种:

采用标准的java线程调用方法。

Thread t = new Thread(r);

t.start();

这种方法与第一种方法等效,与activity同步,同样地,可能产生用户体验差的情况。

当我们启动一个Android应用程序的时候,Android会首先开启一个主线程,这个主线程的工作主要就是管理界面中的UI控件,进行事件分发,处理消息响应函数等。但是如果处理一个比较耗时的操作时,比如读取本地大文档,读取网络数据等等时,如果依然用主线程的话,就会出现问题,Android系统规定默认5S无反应的话,就会弹出强制关闭对话框。

如何解决这个问题,将在解决Handler与Activity同步冲突问题中提到。

-----------------参考Mars老师的讲课内容。

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

相关资料:

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

很多初入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的封装,开发人员可以方便的处理这些异步任务。

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

Android的Handler与Activity线程同步的更多相关文章

  1. Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

    keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...

  2. 解决Handler与Activity同步冲突

    这个问题可以由Handler的一个子类HandlerThread来解决. 程序参考自Mars老师的Android课程第一季第十五集. 代码以及注释有所改动,如下: package com.handle ...

  3. 【转】[Android实例] Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式

    android线程池的理解,晚上在家无事 预习了一下android异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存  下面看他们的理解. [size=1.8em]Handler+Runn ...

  4. [Android实例] Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式

    android线程池的理解,晚上在家无事 预习了一下android异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存  下面看他们的理解. [size=1.8em]Handler+Runn ...

  5. Android的Handler线程切换原理

    Handler是我们在开发中经常会接触到的类,因为在Android中,子线程一般是不能更新UI的. 所以我们会使用Handler切换到主线程来更新UI,那Handler是如何做到实现不同线程之间的切换 ...

  6. 【转】Android - 线程同步

    什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题. 实现同步机制有两个方法: 1.同步代码块 ...

  7. Android多线程研究(3)——线程同步和相互排斥及死锁

    为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码: package com.maso.test; public class ThreadTest2 implements Runn ...

  8. Android多线程研究(3)——线程同步和互斥及死锁

    为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码: package com.maso.test; public class ThreadTest2 implements Runn ...

  9. Android之Handler,举例说明如何更新UI

    方法一:(java习惯,在android不推荐使用) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { ...

随机推荐

  1. bootstrap表格多样式及代码

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...

  2. Java Map接口

    Map接口映射唯一键的值.一个关键是,要使用在日后检索值对象. 给定一个键和一个值,可以在一个Map对象存储的值.后的值被存储时,可以使用它的键检索. 抛出一个NoSuchElementExcepti ...

  3. CNZZ每天百亿条日志写入,SLS+ODPS轻松拆招

    如果你是一个站长,想要提交一个查询,从一亿多条日志中找出从湖南省发出.使用ISP电信.通过百度搜索跳转到达的访问日志.该怎么做? 别急,在接收到您的查询条件后,CNZZ可以快速通过SLS(简单日志服务 ...

  4. 关于更新到Xcode8的一些问题

    随着iOS 10的陆续使用,升级到xcode8也是大势所趋. 虽然现在xcode 8 可能还有一些问题,但是整体还是不错的,对一些常用的插件也做了集成,比如说 ///注释快捷键 下面说一下我遇到的一些 ...

  5. Oracle基础 锁

    一.锁 数据库是一个多用户使用的共享资源.当多个用户并发地存储数据时,数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性. 锁是实现 ...

  6. VMware系统运维(七)vCenter Inventory Server安装

    1.vCenter Inventory Server安装即vCenter 清单服务 2.下一步 3.接受协议,下一步 4.选择安装位置,下一步 5.设置域名,注意在安装之前一定要加域,嘻嘻. 6.设置 ...

  7. 怒刷DP之 HDU 1024

    Max Sum Plus Plus Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  8. POJ 1860 Currency Exchange (最短路)

    Currency Exchange Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u S ...

  9. Python图片处理PIL/pillow/生成验证码/出现KeyError: 和The _imagingft C module is not installed

    最近在用Python开发自己的博客,需要用到Python生成验证码,当然肯定要用到Python的图形处理库PIL,因为我用的是windows. 所以在安装好pil之后就开始写,就按照题目所说出现了Th ...

  10. 【CSS3】---结构性伪类选择器-first-child+last-child

    结构性伪类选择器—first-child “:first-child”选择器表示的是选择父元素的第一个子元素的元素E.简单点理解就是选择元素中的第一个子元素,记住是子元素,而不是后代元素. 示例演示 ...