在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
分享到:
相关推荐
总结来说,子线程中更新UI线程主要有Handler+Looper、Runnable+runOnUiThread以及AsyncTask这三种方式。Handler提供了更灵活的消息机制,适合复杂的同步需求;Runnable+runOnUiThread则更为简洁,适合快速实现简单的...
本文将深入探讨在子线程中更新UI的三种有效方法,并同时讲解如何在Android中获取和处理Message,这是异步通信的关键。 1. **Handler-Looper机制** Handler、Looper和Message是Android系统提供的异步通信框架,用于...
// 子线程中通过UI线程上下文更新UI } private void SetLabelText(object text) { this.label1.Text = text.ToString(); } ``` 在这个例子中,`Post`方法会异步地执行`SetLabelText`方法,确保UI更新在正确的...
### MFC子线程中更新控件内容的两种办法 #### 概述 在MFC应用程序开发中,经常需要在子线程中处理耗时任务,以提高程序的响应速度和执行效率。然而,直接在子线程中更新UI控件可能会导致程序崩溃或不稳定,这是...
3. **runOnUiThread()**:如果你只是需要简单地更新UI,可以直接调用Activity的runOnUiThread()方法,将更新UI的代码包装在一个Runnable中。 ```java MainActivity.this.runOnUiThread(new Runnable() { @...
以上是关于在MFC子线程中使用UI及处理退出、死锁和超时问题的一些核心概念和技术。在实际开发中,理解并正确应用这些知识点对于构建稳定且高效的多线程MFC应用至关重要。Test1文件可能是示例代码或案例分析,具体...
以上四种方法都可以有效地解决WinForms应用中跨线程更新UI的问题,选择哪种方法主要取决于具体需求,如是否需要等待后台操作完成、是否希望简化编程模型等。在实际开发中,通常推荐使用BackgroundWorker,因为它提供...
在 Android 开发中,子线程中更新 UI 是一个常见的需求。由于 Android 的 UI 组件只能在主线程中更新,因此需要使用特殊的方法来实现子线程中更新 UI。本文将介绍六种常见的方法来实现子线程中更新 UI。 方式一:...
在UI线程中调用`show()`方法来显示Dialog,确保不违反Android的UI更新规则——所有的UI操作必须在主线程中进行。然而,如果Dialog的创建过程耗时较长,可能会影响用户体验,这时就需要使用子线程来处理,然后通过...
OkHttp3在Android中的应用和子线程更新UI线程的方法 OkHttp3是一个功能强大且流行的HTTP客户端库,在Android开发中广泛应用于处理HTTP请求。然而,在使用OkHttp3时,需要注意一些关键点,以避免一些常见的错误。 ...
在Android应用开发中,UI(用户界面)的更新必须在主线程中进行,因为主线程是负责处理用户交互和绘制界面的。然而,通常我们会在子线程中执行耗时操作,如网络请求、数据库查询等,以避免阻塞主线程,导致应用无...
在Android开发中,异步任务(AsyncTask)是一种常见的用于执行后台操作并更新UI的工具。它特别适合处理那些不需要长时间运行且需要在完成后更新UI的任务。本篇内容将深入探讨如何在Fragment中使用AsyncTask进行线程...
创建一个新的Windows窗体,添加一个Label控件,然后在子线程中调用`WorkerThreadMethod`,即可看到UI控件的更新。 总之,通过合理使用委托、`Invoke`或`BeginInvoke`,我们可以安全地在子线程中操作UI控件,提高...
这个"wpf 子线程更新UI demo"是一个展示如何在后台线程执行任务并安全更新UI的实例。下面将详细介绍这两种方法及其背后的原理。 1. **Dispatcher对象** WPF提供了一个名为`Dispatcher`的对象,它是每个UI线程的...
在Android开发中,更新UI(用户界面)是常见的任务,特别是在长时间运行的操作或者后台服务中。本教程将探讨如何利用BroadcastReceiver、Service和线程来实现在Android应用中有效地更新UI。以下是对这些知识点的详细...
在Qt编程中,UI(用户界面)的更新通常在主线程中进行,因为GUI(图形用户界面)组件的渲染和事件处理是与主线程紧密关联的。然而,当执行耗时的操作,如网络请求、大数据处理或长时间计算时,如果在主线程中执行,...
4. **Invoke或BeginInvoke方法**:当后台线程需要更新UI时,需要调用Dispatcher的Invoke或BeginInvoke方法。Invoke是同步的,会阻塞当前线程直到UI更新完成;BeginInvoke是异步的,不会阻塞当前线程,而是将更新任务...
本文将深入探讨如何在VS2017的MFC环境中,通过全局函数的方式安全地在子线程中更新控件内容。 首先,理解Windows的消息队列和线程模型是关键。主线程负责处理应用程序的用户界面交互,包括处理消息队列中的消息。当...
2. **AsyncTask**:Android提供的轻量级异步任务类,包含onPreExecute、doInBackground、onProgressUpdate和onPostExecute四个方法,分别在UI线程和后台线程中执行。适合简单的短时间后台任务,可以方便地将结果传递...