`
shinelith
  • 浏览: 8923 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

使用线程更新UI

阅读更多

 

使用线程更新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

    标题“WPF 使用线程更新UI”主要涉及到以下几个关键知识点: 1. **后台线程与主线程**:主线程是负责处理UI事件的线程,任何对UI的操作必须在这个线程上执行。后台线程则用于处理非UI相关的工作,如大数据计算、...

    在Lua中使用线程更新UI

    综上所述,要实现在Lua中使用线程更新UI,开发者需要理解Lua的协程概念,了解C#的线程和UI更新规则,以及如何利用NLua这样的库在C#环境中安全地调用Lua代码。通过这样的技术栈,可以创建出高效且用户体验良好的多...

    C# 线程更新UI界面

    特别是在UI(用户界面)开发中,为了保证界面的流畅性,通常我们会将耗时操作放在后台线程进行,而更新UI则需要在主线程(也称为UI线程)中完成。这是因为UI控件不是线程安全的,多个线程并发访问可能导致数据不一致...

    WPF后台线程更新UI

    - **更新UI**:后台线程完成后,使用`Dispatcher`更新UI元素,如文本框、进度条等。 - **事件处理**:可能包含一个按钮点击事件,触发后台任务,并在任务完成后更新UI。 通过理解并正确使用`Dispatcher`,开发者...

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

    当后台线程需要更新用户界面(UI)时,由于.NET Framework的安全机制,直接操作UI控件会引发“Cross-thread operation not valid”异常。为了解决这个问题,有四种常用的方法:使用Delegate和Invoke、使用Delegate和...

    用多线程更新UI

    在编程领域,尤其是在开发用户界面(UI)时,多线程技术经常被用来优化应用程序的性能和用户体验。本文将深入探讨“用多线程更新...同时,理解线程同步和UI线程的重要性对于编写高效且稳定的多线程UI应用程序至关重要。

    ndroid异步处理一:使用Thread+Handler实现非UI线程更新UI界面

    为了解决这个问题,Android提供了多种异步处理机制,其中一种常见的方式是使用`Thread`配合`Handler`来实现非UI线程执行耗时任务并更新UI。本篇将详细介绍这一方法。 首先,我们需要理解Android的线程模型。Android...

    WPFC#.net 跨线程更新UI 线程测试 解决界面卡死

    Thread 达到跨线程更新UI 虽然使用Dispatcher.Invoke 和模拟winform 里面的DoEvent 但是运行中关闭还是会有异常,而且耗资源高; 第二种 : DispatcherTimer 失败:UI还是会卡顿; 第三种 : Timer 建议使用、资源...

    Winform实现多线程异步更新UI(进度及状态信息)

    为了解决这个问题,开发者通常会采用多线程技术,将耗时任务放在后台线程执行,同时确保UI线程能及时更新进度和状态信息。本文将详细讲解如何在WinForm应用中实现多线程异步更新UI。 1. **线程基础知识**:在...

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

    6. **更新UI的正确方式**:使用`QObject::invokeMethod()`、`QMetaObject::invokeMethod()`或`Qt::QueuedConnection`类型的信号槽连接来确保UI更新在正确的线程中执行。例如,可以创建一个信号,当子线程完成任务时...

    WinForm C# 多线程编程并更新界面(UI)

    下面我们来讨论如何在 WinForm 中使用 C# 实现多线程编程并更新界面(UI)。 多线程编程 多线程编程是一种使应用程序可以同时执行多个任务的技术。它可以提高应用程序的响应速度和用户体验。在 WinForm 中,我们...

    Xamarin.Android 非UI线程更新UI

    4. **Java.Lang.Thread**: 可以创建一个新的Java线程,并在其中执行工作,然后使用`Activity.RunOnUiThread`返回主线程更新UI。 5. **Android.App.ProgressDialog**: 当需要在后台执行耗时操作并希望向用户显示进度...

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

    总之,`AndroidUIUpDemo`项目可能展示了如何在非MainActivity类的子线程中使用OkHttp进行网络请求,并通过上述机制将结果安全地传递给UI线程,进而更新界面。理解并熟练掌握这些通信方式对于开发高效、响应式的...

    多线程更新UI--不错的例子

    不过,由于线程安全问题,直接在非UI线程上修改UI组件可能会导致异常,因此我们需要使用`Control.Invoke`或`Control.BeginInvoke`方法来安全地在UI线程上执行更新UI的操作。 接下来,我们讨论UI更新。在Windows ...

    Android 线程更新UI

    5. **使用RxJava**:一个响应式编程库,可以轻松地处理异步操作和数据流,通过subscribeOn()指定线程,observeOn()切换到主线程更新UI。 ### 四、示例代码 ```java // 创建一个简单的线程 new Thread(new Runnable...

    WinForm后台线程与UI线程通讯

    你可以保存UI线程的SynchronizationContext,并在后台线程中使用Post或Send方法发送回调,更新UI。 4. **async/await**:在C# 5.0及更高版本中,可以利用async/await关键字简化异步编程。后台任务可以标记为async,...

    C#-WinForm跨线程修改UI界面的实例

    本实例“C#-WinForm跨线程修改UI界面的实例”主要展示了如何利用`Task`和`MethodInvoker`来实现跨线程安全地更新UI。`Task`是.NET Framework中的一个类,用于表示异步操作,而`MethodInvoker`是一个委托类型,可以...

    c#多线程中子线程动态改变ui控件

    在上面的代码中,我们首先获取UI线程的同步上下文,然后在子线程中使用Post方法异步更新Label控件的Text属性。 C#子线程更新UI控件有两种常用的方法:使用控件自身的Invoke/BeginInvoke方法和使用...

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

    在C#编程中,特别是在开发桌面应用程序(如WinForms或WPF)时,经常会遇到需要在子线程中更新UI控件的情况。由于UI界面通常运行在主线程中,为保证用户界面的响应性和避免线程冲突,我们需要遵循特定的规则来安全地...

Global site tag (gtag.js) - Google Analytics