`

知识梳理:Android子线程中更新UI的3种方法

 
阅读更多
在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法:

在看方法之前看一下Android中消息机制:


引用

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
Thread:线程,负责调度整个消息循环,即消息循环的执行场所。


不熟悉的朋友可以参考一下这篇文档:
Android知识梳理:消息机制之Handler:http://gqdy365.iteye.com/blog/2148925
Android知识梳理:消息机制之Looper :http://gqdy365.iteye.com/blog/2137494

下面基于上述原理说一下更新方法:
方法一:用Handler

1、主线程中定义Handler:

Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case 0:
				//完成主界面更新,拿到数据
				String data = (String)msg.obj;
				
				updateWeather();
				textView.setText(data);
				break;
			default:
				break;
			}
		}

	};


2、子线程发消息,通知Handler完成UI更新:
private void updateWeather() {
		
		
		new Thread(new Runnable(){

			@Override
			public void run() {
				//耗时操作,完成之后发送消息给Handler,完成UI更新;
				mHandler.sendEmptyMessage(0);
				
				//需要数据传递,用下面方法;
				Message msg =new Message();
				msg.obj = "数据";//可以是基本类型,可以是对象,可以是List、map等;
				mHandler.sendMessage(msg);
			}
			
		}).start();
		
	}

方法一的Handler对象必须定义在主线程中,如果是多个类直接互相调用,就不是很方便,需要传递content对象或通过接口调用;

方法二:用Activity对象的runOnUiThread方法更新
在子线程中通过runOnUiThread()方法更新UI:
new Thread() {
			public void run() {
				//这儿是耗时操作,完成之后更新UI;
				runOnUiThread(new Runnable(){

					@Override
					public void run() {
						//更新UI
						imageView.setImageBitmap(bitmap);
					}
					
				});
			}
		}.start();

如果在非上下文类中(Activity),可以通过传递上下文实现调用;
Activity activity = (Activity) imageView.getContext();
				activity.runOnUiThread(new Runnable() {

					@Override
					public void run() {
						imageView.setImageBitmap(bitmap);
					}
				});

这种方法使用比较灵活,但如果Thread定义在其他地方,需要传递Activity对象;

方法三:View.post(Runnable r)

imageView.post(new Runnable(){

					@Override
					public void run() {
						imageView.setImageBitmap(bitmap);
					}
					
				});


这种方法更简单,但需要传递要更新的View过去;
总结:UI的更新必须在主线程中完成,所以不管上述那种方法,都是将更新UI的消息发送到了主线程的消息对象,让主线程做处理;
  • 大小: 36.4 KB
4
0
分享到:
评论

相关推荐

    子线程中更新UI线程的三种方法

    总结来说,子线程中更新UI线程主要有Handler+Looper、Runnable+runOnUiThread以及AsyncTask这三种方式。Handler提供了更灵活的消息机制,适合复杂的同步需求;Runnable+runOnUiThread则更为简洁,适合快速实现简单的...

    子线程中更新UI的三种方法和获取message的两种方法总结

    本文将深入探讨在子线程中更新UI的三种有效方法,并同时讲解如何在Android中获取和处理Message,这是异步通信的关键。 1. **Handler-Looper机制** Handler、Looper和Message是Android系统提供的异步通信框架,用于...

    C#子线程更新UI控件的方法实例总结

    // 子线程中通过UI线程上下文更新UI } private void SetLabelText(object text) { this.label1.Text = text.ToString(); } ``` 在这个例子中,`Post`方法会异步地执行`SetLabelText`方法,确保UI更新在正确的...

    MFC子线程中更新控件内容的两种办法

    ### MFC子线程中更新控件内容的两种办法 #### 概述 在MFC应用程序开发中,经常需要在子线程中处理耗时任务,以提高程序的响应速度和执行效率。然而,直接在子线程中更新UI控件可能会导致程序崩溃或不稳定,这是...

    安卓UI线程和子线程通讯更新UI实例

    3. **runOnUiThread()**:如果你只是需要简单地更新UI,可以直接调用Activity的runOnUiThread()方法,将更新UI的代码包装在一个Runnable中。 ```java MainActivity.this.runOnUiThread(new Runnable() { @...

    在MFC 子线程中使用UI(控件)退出时死锁或者超时处理参考

    以上是关于在MFC子线程中使用UI及处理退出、死锁和超时问题的一些核心概念和技术。在实际开发中,理解并正确应用这些知识点对于构建稳定且高效的多线程MFC应用至关重要。Test1文件可能是示例代码或案例分析,具体...

    C#WinForm跨线程更新UI的四种方法

    以上四种方法都可以有效地解决WinForms应用中跨线程更新UI的问题,选择哪种方法主要取决于具体需求,如是否需要等待后台操作完成、是否希望简化编程模型等。在实际开发中,通常推荐使用BackgroundWorker,因为它提供...

    Android-dialog库可以在任意类内调用子线程或ui线程内均可显示

    在UI线程中调用`show()`方法来显示Dialog,确保不违反Android的UI更新规则——所有的UI操作必须在主线程中进行。然而,如果Dialog的创建过程耗时较长,可能会影响用户体验,这时就需要使用子线程来处理,然后通过...

    Android 在子线程中更新UI的几种方法示例

    在 Android 开发中,子线程中更新 UI 是一个常见的需求。由于 Android 的 UI 组件只能在主线程中更新,因此需要使用特殊的方法来实现子线程中更新 UI。本文将介绍六种常见的方法来实现子线程中更新 UI。 方式一:...

    详解Android中OkHttp3的例子和在子线程更新UI线程的方法

    OkHttp3在Android中的应用和子线程更新UI线程的方法 OkHttp3是一个功能强大且流行的HTTP客户端库,在Android开发中广泛应用于处理HTTP请求。然而,在使用OkHttp3时,需要注意一些关键点,以避免一些常见的错误。 ...

    Android_子线程创建消息队列更新UI

    在Android应用开发中,UI(用户界面)的更新必须在主线程中进行,因为主线程是负责处理用户交互和绘制界面的。然而,通常我们会在子线程中执行耗时操作,如网络请求、数据库查询等,以避免阻塞主线程,导致应用无...

    android asynctask的fragment更新UI(附线程管理)

    在Android开发中,异步任务(AsyncTask)是一种常见的用于执行后台操作并更新UI的工具。它特别适合处理那些不需要长时间运行且需要在完成后更新UI的任务。本篇内容将深入探讨如何在Fragment中使用AsyncTask进行线程...

    c#子线程操作UI控件的简单委托 包含带参数和不带参数源码

    创建一个新的Windows窗体,添加一个Label控件,然后在子线程中调用`WorkerThreadMethod`,即可看到UI控件的更新。 总之,通过合理使用委托、`Invoke`或`BeginInvoke`,我们可以安全地在子线程中操作UI控件,提高...

    wpf 子线程更新UI demo

    这个"wpf 子线程更新UI demo"是一个展示如何在后台线程执行任务并安全更新UI的实例。下面将详细介绍这两种方法及其背后的原理。 1. **Dispatcher对象** WPF提供了一个名为`Dispatcher`的对象,它是每个UI线程的...

    更新UI android

    在Android开发中,更新UI(用户界面)是常见的任务,特别是在长时间运行的操作或者后台服务中。本教程将探讨如何利用BroadcastReceiver、Service和线程来实现在Android应用中有效地更新UI。以下是对这些知识点的详细...

    qt编程_在子线程中更新UI界面

    在Qt编程中,UI(用户界面)的更新通常在主线程中进行,因为GUI(图形用户界面)组件的渲染和事件处理是与主线程紧密关联的。然而,当执行耗时的操作,如网络请求、大数据处理或长时间计算时,如果在主线程中执行,...

    WPF 使用线程更新UI

    4. **Invoke或BeginInvoke方法**:当后台线程需要更新UI时,需要调用Dispatcher的Invoke或BeginInvoke方法。Invoke是同步的,会阻塞当前线程直到UI更新完成;BeginInvoke是异步的,不会阻塞当前线程,而是将更新任务...

    VS2017-MFC子线程中更新控件的内容框架代码

    本文将深入探讨如何在VS2017的MFC环境中,通过全局函数的方式安全地在子线程中更新控件内容。 首先,理解Windows的消息队列和线程模型是关键。主线程负责处理应用程序的用户界面交互,包括处理消息队列中的消息。当...

    Android两个子线程之间的通信

    2. **AsyncTask**:Android提供的轻量级异步任务类,包含onPreExecute、doInBackground、onProgressUpdate和onPostExecute四个方法,分别在UI线程和后台线程中执行。适合简单的短时间后台任务,可以方便地将结果传递...

Global site tag (gtag.js) - Google Analytics