Android学习笔记:更新UI的方法(UI线程和非UI线程)

Android异步处理一:使用Thread+Handler实现UI线程更新UI界面 本博文地址:http://blog.csdn.net/mylzc/article/details/6736988 转载请注明出处 Android异步处理系列文章索引 Android异步处理一:使用Thread+Handler实现UI线程更新UI界面 阅读详情

一、UI线程以及Android的单线程模型原则

当应用启动时,系统会创建一个主线程(Main Thread)。这个主线程负责向UI组件分发事件(包括绘制事件),在这个主线程里,应用和Android的UI组件发生交互。所以Main Thread也叫UI Thread也即UI线程。

系统不会为每个组件单独创建线程,在同一个进程里的UI组件都会在UI线程里实例化,系统对每一个组件的调用都从UI线程分发出去。结果就是在响应系统回调的方法永远都是在UI线程里运行。当App做一些比较重的工作的时候,除非你合理地实现,否则单线程模型的性能会很差。

特别的是,如果所有的工作都在UI线程,做一些比较耗时的工作比如访问网络或数据库查询,都会阻塞UI线程,导致事件停止分发(包括绘制事件)。对于用户来说,应用看起来像是卡住了,更坏的情况是,如果UI线程blocked的时间太长(大约超过5秒),用户就会看到ANR(Application Not Responding)的对话框。

此外,Android UI工具包并不是线程安全的,所以不能从非UI线程来操纵UI组件。必须把所有UI操作放在UI线程里。所以Android单线程模型有两条原则:
(1)不要阻塞UI线程。
(2)不要在UI线程之外访问Android UI工具包。(主要是这两个包中的组件:android.widget和android.view)


二、使用Worker线程

根据单线程模型的两条原则,首先,要保证应用的响应性,不能阻塞UI线程,所以当你的操作不是即时的那种,你应该把他们放在单另的线程中(叫做background或者work线程)。

例如:比如点击按钮后,下载一个图片然后在ImageView中展示:

public void onClick(View v){
   
   
	new Thread(new Runnable(){
   
   
		public void run(){
   
   
			Bitmap b = loagImageFromNetwork("http://example.com/image.png");
			mImageView.setImageBitmap(b);
		}
	}).start();
}

上面这段代码用新的线程来处理网络操作,但是它违反了第二条原则:Do not access the Android UI toolkit from outside the UI thread.(从非UI线程访问UI组件会导致未定义和不能预料的行为。)


三、交互方式

Android提供了一些方法,用于实现后台线程与UI线程的交互。

1、Handler(线程间通讯)(推荐)

在Android中我们一般用Handler做主线程和子线程之间的通信。Handler是Android中专门用来在线程之间传递信息类的工具。

原理:Handler的作用是将一个任务切换到某个指定的线程中去执行。系统之所以提供Handler,主要原因就是为了解决在子线程中无法访问UI的矛盾。(需要注意的是,Handler并不是专门用于更新UI的,它只是常被开发者用来更新UI。)

关于Handler的具体分析,请点击跳转。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
   
   

    public static final int UPDATE_TEXT = 1;

    private TextView textView;

    private Buttion button;

	//在主线程中定义接收函数
    private Handler handler = new Handler(){
   
   
        //重写父类handleMessage()方法
        public void handleMessage(Message msg){
   
   
            switch(msg.what){
   
   
                case UPDATE_TEXT:
                    //在这里可以进行UI操作
                    textView.setText("更新");
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.tv);
        button = (Buttion)findViewById(R.id.btn);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v){
   
   
        switch(v.getId()){
   
   
            case R.id.btn:
                new Thread(new Runnable(){
   
   
                    @Override
                    public void run(){
   
   
                        Message message = new Message<
Android UI线程UI线程 UI线程Android的单线程模型原则  当应用启动,系统会创建一个主线程(main thread)。  这个主线程负责向UI组件分发事件(包括绘制事件),也是在这个主线程里,你的应用AndroidUI组件(components from the Android UI toolkit (components from the android.widget andandroid.view pa... 阅读详情

相关推荐

SPI模式下的SD卡读写,为什么你的数据总出错?详解时序与状态机避坑指南

本文深入探讨SPI模式下SD卡读写数据出错的根本原因,提供时序优化与状态机设计的实战指南。针对时钟周期计数、状态机跳转忙检测等核心问题,详解命令时序细节、状态机同步策略及高级避坑技巧,帮助开发者提升SD卡在SPI模式下的稳定性性能。

weixin_30514745的博客 238

为什么必须在主线程操作UI

系统: Mac OS 10.14.6, XCode 11,swift 4.2 写作时间:2019-10-12 说明 写iOS的同学都知道,如果更新update UI不在主线程,直接crash。那到底为什么,update UI必须要在主线程呢?原因有如下3点: 1. 在Cocoa Touch, UIApplication建立在主线程,这个单例是App启动的第一部分。 所有在屏幕上面的Views,La...

AI架构师易筋 1107

C#上位机案例:西门子S7协议通信+实时曲线显示(WinForm+ZedGraph)

创建/// PLC数据模型(对应DB1块)/// 采集时间(用于曲线的X轴)set;/// 温度值(℃)set;/// 压力值(MPa)set;/// PLC通信状态set;西门子S7协议通信实时曲线显示,也是工控现场最常见的场景之一。整个开发过程的关键不在于“写出代码”,而在于“写出符合工控场景的稳定代码”——比如解耦通信逻辑与界面逻辑、处理跨线程问题、限制数据点数量、释放资源等。新手在学习时,建议先跟着步骤搭建好环境,跑通基础功能,再逐步尝试进阶优化。需要注意的是,工控上位机的核心是。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1290

ui线程UI线程

ui线程UI线程的两点总结: 第一,对UI界面元素的操作,需要UI元素处于UI线程中 [code="java"] Display.getDefault().asyncExec(new Runnable() { //对UI元素的操作 }); [/code] 第二,如果UI线程被阻塞,则界面产生白屏...

小嘴冰凉 530

Android线程 (UI线程)线程的用法

1.在android中,我们常两种线程交互,分别为UI线程(又叫主线程),还有一种是子线程(Thread,Runnable) 2.主线程UI线程 2.1从名字看下,UI线程,顾名思义就是UI交互的线程UI线程一般处理低耗时的UI操作(5秒以内的耗时), 常见的有:UI更新,Toast的弹起。popwin以及dialog的 子线程:目前比较常见的就是网络的请求,必须在UI线程操作。还有其他的耗时操作 3.如何判断当前线程执行在主线程还是子线程: booean isMainThread=L

4290

安卓中的几种线程间通信方式

一:Handler实现线程间的通信          andriod提供了 Handler Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。 在Android,这里的线程分为有消息循环的线程没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 ...

small_and_smallworld 1万+

Android线程UI线程)的理解

## 网络连接需要时间。Web服务器可能需要1~2秒的时间来响应,文件下载则耗时更久。考虑 到这个因素,Android禁止任何主线程网络连接行为。即使强行为之,Android也会抛出 NetworkOnMainThreadException异常。 这是为什么呢?要想知道答案,首先要知道什么是线程,什么是主线程,主线程有什么用途。 线程是个单一执行序列。单个线程中的代码会逐步执行。所有Android应用的运行都是从主 线程开始的。然而,主线程不是线程那样的预定执行序列。相反,它处于一个无限循环的运行状 态,等

u010194271的博客 2216

为什么我们可以在UI线程更新UI

看到这样的标题……估计N多人会说我是逗比…………因为很多盆友在学习Android(特别是从4.0之后开始入门的)的时候都会常看见或听到别人说我们更新UI呢要在UI线程(或者说主线程)中去更新UI,不要在子线程更新UI,而Android官方呢也建议我们不要在UI线程直接更新UI,为什么呢?借助Android官方的一句话来说就是: “The Android UI toolkit is not thread-safe and the view must always be manipulated on the

AigeStudio 2万+

AndroidUI线程直接更新UI信息

Android 说明文档明确指出不能在UI线程直接更新UI线程的信息,否则系统会抛出类似如下异常: 09-15 21:37:09.335: E/AndroidRuntime(4507): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view h

Inspiration 1万+

AndroidUI线程更新UI方法

1、使用Thread+Handler实现UI线程更新UI界面

寒江蓑笠的专栏 1690

android 不能在子线程更新ui的讨论分析

问题描述  做过android开发基本都遇见过ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是只能在主线程中更改ui,子线程要修改ui只能post到主线程或者使用handler之类。但是仔细看看exception的描述并不是这样的,“Only the original thread that created a view hierar

Shawn_Dut的专栏 1万+

Android在子线程更新UI

Android在子线程更新UI

Android应用开发工程师 1956

UI线程更新UI问题

我们都知道在android中我们想更新一个ui,一定要在主线程更新,也就是UI线程。因为这我们的安卓系统设计有关,安卓的系统设计是单线程模式。 规定 更新ui必须在主线程中 那么会存在一些情况违反了这种规定,但又偏偏没有报错,运行成功。 第一种情况,我们直接在onCreate中开启一个子线程更新ui,这是成功的。为什么呢?因为我们的视图绘制是由ViewRootImpl来管理,而ViewRoot...

weixin_41078100的博客 479

Android 】为什么 UI 线程不能更新 UI

什么是UI线程 Android的核心进程zygote进程fork出我们的app,app启动的最终会走入到ActivityThread中的main方法,在main方法中会调用Looper。其中ActivityThread所在的线程被称为UI线程,也就是我们常说的主线程 (Main thread)。 关于Main thread这个称呼其实可以查看ActivityThread中main方法的源码: ...

weixin_45365889的博客 720

AndroidUIUtil 工具类

工具类: public class UIUtil { /*** * 获取本机IP * @param context * @return */ public static String getIP(Context context){ try { for (Enumeration<NetworkInterface> en = NetworkInterf...

lizhong 951

[Silverlight] 如何在 Worker thread 中更新 UI

Silverlight 中调用服务全部采用异步方式,在调用 WCF 时似乎没有什么问题。但是如果要用一个 WebRequest 对象去向某个页面 Post 一些内容,然后获得回应。就会发现在 Worker thread 中将无法更新 UI.在 Windows Forms 里,可以用 Control.Invoke. 但是 Silverlight 没有这个。Silverlight 中有更好的办

木野狐@CSDN Blog 399

Android:UI更新方法:在Worker Thread中runOnUiThread直接刷新UI

activity_main.xml: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:la

混迹于移动互联网和手机行业 1万+

android中子线程更新UI的方式浅析

android中子线程更新UI的方式浅析 2015-05-25      0 个评论    来源:安诺爱成长   收藏    我要投稿 一、为何写作此文 ??你是不是经常看到很多书籍中说:不能在子线程操作ui,不然会报错。你是不是也遇到了如下的疑惑(见下面的代码): ? 1 2 3 4 5 6

378

深入理解Handler() --- Android中为什么UI线程不能更新UI

一、前言 通过这篇文章带大家了解以下内容 是否能够理解UI线程的工作机制 是否熟悉SurfaceView实现高帧率的原理 二、为什么UI线程不能更新UI 这个问题我们要从以下几个方面来探讨 UI线程的工作机制 为什么UI设计成线程不安全的 UI线程一定不能更新UI吗 2.1 UI线程是什么怎么来的 我们知道所有的App进程通过 Zygote fork出来,当我们的App进程启动后会执行 ActivityThread的main函数,在main函数里会调用Looper对象调用loop函数 p

soso密斯密斯的博客 790

智能网联汽车概述智能网联汽车技术基础

智能网联汽车的内涵认知智能网联汽车结构及技术体系认知智能网联汽车发展趋势认知

上一篇: Android学习笔记:OkHttp
下一篇: Android学习笔记:Volley
浩比浩比
博客等级 码龄12年 395粉丝 202原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值