`

【Android】UI界面外的线程,控制刷新UI界面

 
阅读更多

一,问题引入

异常: Only the original thread that created a view hierarchy can touch its views的解决方案

<wbr><wbr><wbr><wbr>为什么会有这种异常产生呢?</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>当每个应用程序apk第一次启动时,Android会同时启动一个对应的<span style="color:#ff0000; line-height:21px; word-wrap:normal; word-break:normal">主线程(Main Thread)</span>,</wbr></wbr></wbr>
<wbr><wbr><wbr>主线程负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,</wbr></wbr></wbr>
<wbr><wbr><wbr>并把相关的事件分发到对应的组件进行处理,所以主线程通常又被叫做<span style="color:#ff0000; line-height:21px; word-wrap:normal; word-break:normal">UI线程</span>。</wbr></wbr></wbr>

<wbr><wbr><wbr>但是在开发Android应用时必须遵守单线程模型的原则:<wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><span style="color:#ff0000; line-height:21px; word-wrap:normal; word-break:normal">Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行,如果在非UI线程中直接操作UI线程,</span></wbr></wbr></wbr>
<wbr><wbr><wbr>会抛出android.view.ViewRoot$CalledFromWrongThreadExc<wbr>eption: Only the original thread that<wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>created a view hierarchy can touch its views,这与普通的java程序不同。</wbr></wbr></wbr>

<wbr><wbr><wbr><wbr>由于UI线程负责事件的监听和绘图,因此,必须保证UI线程能够随时响应用户的需求,</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>UI线程里的操作应该向中断事件那样短小,费时的操作(如网络连接)需要另开线程,</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>否则,如果UI线程超过5s没有响应用户请求,会弹出对话框提醒<span style="color:#ff0000; line-height:21px; word-wrap:normal; word-break:normal">用户终止应用程序(ANP)</span>。</wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr>如果在新开的线程中需要对UI进行设定,就可能违反单线程模型,</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>因此android采用一种的Message Queue机制保证<span style="color:#ff0000; line-height:21px; word-wrap:normal; word-break:normal">线程间通信</span>。</wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr>Message Queue是一个消息队列,用来存放通过Handler发送的消息。</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr>Android在第一启动程序时会默认会为UI thread创建一个关联的消息队列,</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>可以通过Looper.myQueue()得到当前线程的消息队列,用来管理程序的一些上层组件,</wbr></wbr></wbr>
<wbr><wbr><wbr>activities,broadcast receivers 等,你可以在自己的子线程中创建Handler与UI thread通讯。</wbr></wbr></wbr>

<wbr><wbr><wbr>Handler会向message queue通过两种方法发送消息:send或post。</wbr></wbr></wbr>
<wbr><wbr><wbr>这两种消息都会插在message queue队尾并按先进先出执行,</wbr></wbr></wbr>
<wbr><wbr><wbr>但通过这两种方法发送的消息执行的方式略有不同:</wbr></wbr></wbr>
<wbr><wbr><wbr>1)通过send发送的是一个message对象,<wbr>会被handler的 handleMessage()函数处理;</wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>2)而通过post方法发送的是一个runnable对象,则会自己执行。</wbr></wbr></wbr>

<wbr><wbr><wbr>每个带图形界面的应用启动后,都会创建一个主线程,可称之为UI线程。</wbr></wbr></wbr>
<wbr><wbr><wbr>这个线程自动就会创建一个message queue,来自于系统的消息都会投放到这个message queue里面,</wbr></wbr></wbr>
<wbr><wbr><wbr>并按先进先出的顺序处理。</wbr></wbr></wbr>

<wbr><wbr><wbr>UI线程图形界面中的view可通过post方法向GUI线程的message queue投递一个runnable。</wbr></wbr></wbr>
<wbr><wbr><wbr>对于除UI线程以外的其他线程,创建时缺省并没有message queue,</wbr></wbr></wbr>
<wbr><wbr><wbr>而对于UI线程,则可以直接(比如在onCreate)创建一个handler并重载handleMessage,</wbr></wbr></wbr>
<wbr><wbr><wbr>省去创建message queue的过程。</wbr></wbr></wbr>
二,解决方案一


四,特别注意,引入函数包得时候,不要引入错误的包

import android.os.Handler; //这是正确的包

import java.util.logging.Handler;//不是这个包,而是上一个

分享到:
评论

相关推荐

    Android 实现界面刷新的几种方法

     Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 Android程序中可以使用的界面...

    android ui界面时间刷新

    在Android应用开发中,UI界面的时间刷新是一个常见的需求,特别是在显示实时信息如系统时间、倒计时或计时器等场景。本篇文章将深入探讨如何使用Handler机制来实现在Android UI界面上对系统时间的实时更新。 ...

    Android线程中操作UI界面的方法

    本文将详细介绍四种常见的在Android线程中操作UI界面的方法:使用Handler、View.post(Runnable)、Activity.runOnUiThread(Runnable)以及AsyncTask。 ### 1. 使用Handler **原理**: `Handler`机制是Android中处理...

    Android 多线程下载+UI进度条刷新

    在Android开发中,多线程下载以及UI进度条的实时刷新是常见的需求,尤其是在处理大文件下载时。本文将深入探讨如何实现这个功能,并参考了链接`http://blog.csdn.net/sky286753213/article/details/11770299`中的...

    Android-UI刷新

    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 Android程序中可以使用的界面刷新...

    android UI 各种小例子

    在Android中,由于主线程不能进行耗时操作,所以通常会用到AsyncTask或Handler/Looper机制来在后台线程处理数据,并在UI线程上更新界面。 2. **UI-LinearLayout**: LinearLayout是Android中最基础的布局管理器之...

    Android 使用AsyncTask异步更新UI界面

    本文将详细探讨如何在Android中使用`AsyncTask`来异步更新UI界面。 ### 一、AsyncTask概述 `AsyncTask`是Android SDK提供的一种轻量级的异步任务处理类,它简化了在后台线程中执行任务并在UI线程中更新结果的过程...

    Android异步刷新UI多种实现方案

    在Android开发中,异步刷新UI是至关重要的,它能够保证用户界面的流畅性,避免因为长时间阻塞主线程导致的ANR(Application Not Responding)错误。本篇将详细介绍Asynctask、Handler+Thread以及TimerTask这三种常见...

    ListView下拉刷新界面UI

    "ListView下拉刷新界面UI"就是这样一个功能,它允许用户在顶部下拉ListView,然后松开手指时自动开始加载新数据。 实现ListView的下拉刷新功能通常涉及以下关键知识点: 1. **SwipeRefreshLayout**:这是Android ...

    为何SurfaceView能够在非UI线程中刷新界面(内容为代码的demo而并非文档)

    在Android系统中,UI操作必须在主线程(也称为UI线程)中执行,这是为了保证用户界面的流畅性和一致性。然而,对于某些高性能的图形处理或者视频播放场景,如游戏或摄像头应用,使用主线程可能会导致性能瓶颈,因为...

    Android UI界面漂亮的天气预报源码.zip

    这份名为"Android UI界面漂亮的天气预报源码.zip"的压缩包文件包含了一个用于构建美观的Android天气预报应用的源代码。这个源码项目是开发者们学习Android UI设计、天气API集成以及应用程序开发的一个优秀资源。下面...

    Android广播onReceiver回调更新ui

    "Android广播onReceiver回调更新ui"这个主题主要涉及如何在广播接收器中处理接收到的广播消息,并在用户界面(UI)上做出相应的更新。我们将深入探讨以下几个关键知识点: 1. **广播机制**: Android系统通过发送...

    安卓通过线程刷新view的例子

    在上述的“安卓通过线程刷新view的例子”中,可能涉及到的技术包括: 1. **runOnUiThread()**:这是一个Activity提供的方法,可以直接在非UI线程中调用,将指定的Runnable对象放入主线程的消息队列,等待主线程执行...

    android动态刷新界面

    在Android开发中,动态刷新界面是一项至关重要的技能,它涉及到用户界面(UI)的实时更新,使得应用能够根据用户的操作或者后台数据的变化实时反映到屏幕上。权重(weight)的使用则是Android布局管理中的一个关键...

    android 界面刷新count

    总之,“android界面刷新count”是一个关于优化Android应用界面更新的话题,涉及主线程与子线程的协作、界面更新的最佳实践以及性能监控。开发者应熟练掌握这些技术,以提供更流畅、更高效的用户体验。

    Android界面刷新的方法分享

    在 Android 中,UI 操作并不是线程安全的,这意味着我们不能直接在线程中调用 Invalidate() 方法来刷新界面。为了解决这个问题,我们可以使用 Handler 来实现界面刷新。Handler 是 Android 中的一种特殊的线程间通信...

    Android UI组件实例集合

    是一个工具包用来帮助设计和开发 Android 用户界面,包含三个单独的工具:Android Asset Studio用户界面原型模具,Android 设计预览,时常需要重复确认程序版面设计状况的 Android App 开发者,应该会爱上这个轻量级...

    Android的线程使用来更新UI

    在Android开发中,由于UI操作必须在主线程(也称为UI线程)中进行,因此在后台线程处理任务并更新界面时需要遵循特定的机制。以下是对标题和描述中涉及知识点的详细解释: 1. **线程模型**: Android系统采用单...

    Android qq界面详细设计

    总的来说,"Android qq界面详细设计"是一个综合性的课题,涵盖了Android UI设计原则、组件使用、交互设计、性能优化等多个方面。通过深入研究QQ的源代码,开发者不仅可以提升自己的Android界面设计能力,还能借鉴其...

Global site tag (gtag.js) - Google Analytics