使用线程更新UI
关键字 Thread
线程
停止
日期 2010/7/31
简述
当第一次启动一个Android
程序时,Android
会自动创建一个称为“main”
主线程的线程。这个主线程(也称为UI
线程)很重要,因为它 负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与Andriod
控件交互的线程。比如,当你在屏幕上按下一个按钮后,UI
线程会把这
个事件分发给刚按得那个按钮,紧接着按钮设置它自身为被按下状态并向事件队列发送一个无效(invalidate
)请求。UI
线程会把这个请求移出事件队 列并通知按钮在屏幕上重新绘制自身。
单线程模型会在没有考虑到它的影响的情况下引起Android
应用程序性能低下,因为所有的任务都在同一个线程中执行,如果执行一些耗时的操作,如 访问网络或查询数据库,会阻塞整个用户界面。当在执行一些耗时的操作的时候,不能及时地分发事件,包括用户界面重绘事件。从用户的角度来看,应用程序看上
去像挂掉了。更糟糕的是,如果阻塞应用程序的时间过长(现在大概是5
秒钟)Android
会向用户提示一些信息,即打开一个“
应用程序没有相应 (application not responding
)”
的对话框。
如果你想知道这有多糟糕,写一个简单的含有一个按钮的程序,并为按钮注册一个单击事件,并在事件处理器中调用这样的代码 Thread.sleep(2000)
。在按下这个按钮这后恢复按钮的正常状态之前,它会保持按下状态大概2
秒钟。如果这样的情况在你编写的应用程序中发 生,用户的第一反应就是你的程序运行很慢。
现在你知道你应该避免在UI
线程中执行耗时的操作,你很有可能会在后台线程或工作者线程中执行这些耗时的任务,这样做是否正确呢?让我们来看一个例子,在这个例子中按钮的单击事件从网络上下载一副图片并使用ImageView
来展现这幅图片。代码如下:
public void onClick(View v){
new Thread( new Runnable(){
public void run(){
Bitmap b = loadImageFromNetwork();
mImageView.setImageBitmap(b);
}
}).start();
}
这段代码好像很好地解决了你遇到的问题,因为它不会阻塞UI
线程。很不幸,它违背了单线程模型:Android UI
操作并不是线程安全的并且这些操作必须在UI
线程中执行。
使用Handler
来更新UI
建立一个线程,设一个boolean
变量来控制线程的运行,当收到被调用
interrupt()
时就产生InterruptedException
异常,catch
异常后改变变量,这样就可以停止线程了。
private Thread thread = new Thread() {
@Override
public void run() {
boolean running = true;
while (running) {
try {
settime.sendMessage(settime.obtainMessage());
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.d("Thread", "Exception");
running =false;
}
}
}
};
Handler
可以认为是消息队列,线程发送消息,主线程中的Handler
收到消息,更新UI
,这样就避免了UI
在线程中被更新。
private Handler settime = new Handler() {
Time t = new Time();
String time = new String();
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
t.setToNow();
tv_time.setText(time.format("%2d:%2d %d", t.hour, t.minute, t.second));
}
};
调用interrupt()
以停止线程运行
b_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
thread.interrupt();
}
});
分享到:
相关推荐
标题“WPF 使用线程更新UI”主要涉及到以下几个关键知识点: 1. **后台线程与主线程**:主线程是负责处理UI事件的线程,任何对UI的操作必须在这个线程上执行。后台线程则用于处理非UI相关的工作,如大数据计算、...
综上所述,要实现在Lua中使用线程更新UI,开发者需要理解Lua的协程概念,了解C#的线程和UI更新规则,以及如何利用NLua这样的库在C#环境中安全地调用Lua代码。通过这样的技术栈,可以创建出高效且用户体验良好的多...
特别是在UI(用户界面)开发中,为了保证界面的流畅性,通常我们会将耗时操作放在后台线程进行,而更新UI则需要在主线程(也称为UI线程)中完成。这是因为UI控件不是线程安全的,多个线程并发访问可能导致数据不一致...
- **更新UI**:后台线程完成后,使用`Dispatcher`更新UI元素,如文本框、进度条等。 - **事件处理**:可能包含一个按钮点击事件,触发后台任务,并在任务完成后更新UI。 通过理解并正确使用`Dispatcher`,开发者...
当后台线程需要更新用户界面(UI)时,由于.NET Framework的安全机制,直接操作UI控件会引发“Cross-thread operation not valid”异常。为了解决这个问题,有四种常用的方法:使用Delegate和Invoke、使用Delegate和...
在编程领域,尤其是在开发用户界面(UI)时,多线程技术经常被用来优化应用程序的性能和用户体验。本文将深入探讨“用多线程更新...同时,理解线程同步和UI线程的重要性对于编写高效且稳定的多线程UI应用程序至关重要。
为了解决这个问题,Android提供了多种异步处理机制,其中一种常见的方式是使用`Thread`配合`Handler`来实现非UI线程执行耗时任务并更新UI。本篇将详细介绍这一方法。 首先,我们需要理解Android的线程模型。Android...
Thread 达到跨线程更新UI 虽然使用Dispatcher.Invoke 和模拟winform 里面的DoEvent 但是运行中关闭还是会有异常,而且耗资源高; 第二种 : DispatcherTimer 失败:UI还是会卡顿; 第三种 : Timer 建议使用、资源...
为了解决这个问题,开发者通常会采用多线程技术,将耗时任务放在后台线程执行,同时确保UI线程能及时更新进度和状态信息。本文将详细讲解如何在WinForm应用中实现多线程异步更新UI。 1. **线程基础知识**:在...
6. **更新UI的正确方式**:使用`QObject::invokeMethod()`、`QMetaObject::invokeMethod()`或`Qt::QueuedConnection`类型的信号槽连接来确保UI更新在正确的线程中执行。例如,可以创建一个信号,当子线程完成任务时...
下面我们来讨论如何在 WinForm 中使用 C# 实现多线程编程并更新界面(UI)。 多线程编程 多线程编程是一种使应用程序可以同时执行多个任务的技术。它可以提高应用程序的响应速度和用户体验。在 WinForm 中,我们...
4. **Java.Lang.Thread**: 可以创建一个新的Java线程,并在其中执行工作,然后使用`Activity.RunOnUiThread`返回主线程更新UI。 5. **Android.App.ProgressDialog**: 当需要在后台执行耗时操作并希望向用户显示进度...
总之,`AndroidUIUpDemo`项目可能展示了如何在非MainActivity类的子线程中使用OkHttp进行网络请求,并通过上述机制将结果安全地传递给UI线程,进而更新界面。理解并熟练掌握这些通信方式对于开发高效、响应式的...
不过,由于线程安全问题,直接在非UI线程上修改UI组件可能会导致异常,因此我们需要使用`Control.Invoke`或`Control.BeginInvoke`方法来安全地在UI线程上执行更新UI的操作。 接下来,我们讨论UI更新。在Windows ...
5. **使用RxJava**:一个响应式编程库,可以轻松地处理异步操作和数据流,通过subscribeOn()指定线程,observeOn()切换到主线程更新UI。 ### 四、示例代码 ```java // 创建一个简单的线程 new Thread(new Runnable...
你可以保存UI线程的SynchronizationContext,并在后台线程中使用Post或Send方法发送回调,更新UI。 4. **async/await**:在C# 5.0及更高版本中,可以利用async/await关键字简化异步编程。后台任务可以标记为async,...
本实例“C#-WinForm跨线程修改UI界面的实例”主要展示了如何利用`Task`和`MethodInvoker`来实现跨线程安全地更新UI。`Task`是.NET Framework中的一个类,用于表示异步操作,而`MethodInvoker`是一个委托类型,可以...
在上面的代码中,我们首先获取UI线程的同步上下文,然后在子线程中使用Post方法异步更新Label控件的Text属性。 C#子线程更新UI控件有两种常用的方法:使用控件自身的Invoke/BeginInvoke方法和使用...
在C#编程中,特别是在开发桌面应用程序(如WinForms或WPF)时,经常会遇到需要在子线程中更新UI控件的情况。由于UI界面通常运行在主线程中,为保证用户界面的响应性和避免线程冲突,我们需要遵循特定的规则来安全地...