`
chriszeng87
  • 浏览: 738857 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android线程模型

阅读更多

 当第一次启动一个Android程序时,Android会自动创建一个称为“main”主线程的线程。
这个主线程(也称为UI线程)很重要,因为它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与Andriod控件交互的线程。比如,当你在屏幕上按下一个按钮后,UI 线程会把这个事件分发给刚按得那个按钮,紧接着按钮设置它自身为被按下状态并向事件队列发送一个无效(invalidate)请求。UI线程会把这个请求移出事件队列并通知按钮在屏幕上重新绘制自身。

另外4大组件的生命周期函数也是通过该线程来调用的。 比如Activity的oncreate(),OnResume()函数,BroadcastReceiver的onReceive()) 
单线程模型会在没有考虑到它的影响的情况下引起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线程中执行。在这段代码片段中,在一个工作者线程中使用ImageView的方法,这回引起一些很古怪的问题。查处这个问题并修复这个bug会很困难而且也很耗时。

Andriod提供了几种在其他线程中访问UI线程的方法。或许你已经对其中的一些方式很熟悉,但下面是一个更全面的列表:

    * Activity.runOnUiThread( Runnable )
    * View.post( Runnable )
    * View.postDelayed( Runnable, long )
    * Hanlder

上面的任何一个类或方法都可以修复我们前面代码中出现的问题

很不幸的是这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。
在Android 1.0和1.1中具有与AsyncTask相同功能的类UserTask。它提供了完全一样的API,你需要做的只是把它的代码拷贝的你的程序中。
AsyncTask的目标是替你管理你的线程。前面的代码可以很容易地使用AsyncTask重写。

正如你看到的,使用AsyncTask必须要继承它。使用AsyncTask非常重要的是:AsyncTask的实例必须在UI线程中创建而且只能被使用一次。你可以使用预读AsyncTask的文档来来了解如何使用这个类,下面大概地了解一下它是如何工作的:

    * 你可以使用泛型参数制定任务的参数、中间值(progress values)和任何的最终执行结果
    * doInBackground()方法会自动地在工作者线程中执行
    * onPreExecute()、onPostExecute()和onProgressUpdate()方法会在UI线程中被调用
    * doInBackground()方法的返回值会被传递给onPostExecute()方法
    * 在doInBackground()方法中你可以调用publishProgress()方法,每一次调用都会使UI线程执行一次 onProgressUpdate()方法
    * 你可以在任何时候任何线程中取消这个任务

除了官方的文档,你可以阅读Shelves和Photostream源代码中的几个复杂的示例。我强烈地推荐阅读Shelves的源代码,它会使你知道如何在配置更改之间持久化任务以及在activity被销毁时正确的取消任务。

不管是否使用AsyncTask,始终记住以下两个关于单线程模型的准则:不要阻塞UI线程以及一切Android UI操作都在UI线程中执行。AsyncTask仅仅是使你能够更容易地遵守这两条准则。

另外,关于AsyncTask的更多内容请参考《AsyncTask
 
分享到:
评论

相关推荐

    浅谈android线程模型

    ### 浅谈Android线程模型:深入理解与实践 #### 引言 随着智能手机的普及和技术的不断进步,Google的Android操作系统成为了移动设备领域的重要力量。Android不仅为用户提供了丰富的功能,也为开发者提供了广阔的...

    android 线程模型

    Android线程模型是Android应用程序设计中的关键概念,主要涉及如何有效地管理多线程以避免阻塞用户界面,确保应用的流畅性和响应性。在Android系统中,主线程,也被称为UI线程,是应用程序的核心,它负责处理所有的...

    android多线程模型和service分析

    #### Android线程模型详解 Android的线程模型围绕主线程构建,主线程维护了一个消息队列,不断从队列中取出消息进行处理。当队列为空时,主线程处于等待状态,直到有新消息加入队列。 为了实现多线程间的通信,...

    android线程 Handler Message Queue AsyncTask线程模型 线程交互 + 修改Button样式 示例 最终easy整合版

    1. **Android线程模型** Android系统的主线程,也称为UI线程,负责处理用户界面的所有交互。为了防止UI阻塞,开发者需要在其他线程中执行耗时操作。主要有以下几种线程模型: - **Worker Thread**:开发者自定义...

    android 线程之间通过Handler发送消息

    首先,理解Android线程模型至关重要。Android应用的主要工作线程被称为UI线程或主线程,它负责处理用户界面的更新和事件响应。后台线程通常用于执行耗时任务,避免阻塞UI线程。为了在后台线程和主线程之间交换数据和...

    Android 线程更新UI

    在学习和实践中,理解Android线程模型和正确更新UI的方法对于提升应用性能和用户体验至关重要。确保遵循最佳实践,避免主线程阻塞,合理安排任务执行,以及正确处理线程间的通信。通过实践和调试,你将能熟练掌握...

    Android多线程下载(二)

    总之,Android多线程下载涉及到了Android线程模型、并发控制、文件操作等多个方面,需要开发者有扎实的基础知识和实践经验。通过合理利用多线程,不仅可以提升应用性能,还能提高用户满意度。在实际开发中,要根据...

    Xamarin.Android 非UI线程更新UI

    总结起来,Xamarin.Android的非UI线程更新UI涉及了对Android线程模型的理解以及各种线程间通信技术的运用。通过Handler、RunOnUiThread、AsyncTask等方法,我们可以确保UI操作始终在主线程中安全执行。遵循最佳实践...

    [毕设季 android开发]第六讲:Android线程及UI更新

    1. **Android线程模型**: - **主线程(UI线程)**:处理用户交互,更新UI。 - **工作线程**:执行耗时任务,不直接操作UI,以免阻塞主线程。 - **Handler、Looper和Message的关系**:Handler发送Message到消息...

    Android平台多线程文件下载器

    首先,理解Android线程模型至关重要。基于Java的多线程原理,Thread和AsyncTask可用于后台任务处理,但避免主线程执行耗时操作,以防ANR。多线程下载应在工作线程中执行,保持UI响应。 实现多线程下载,关键在于...

    Android 多线程下载

    在Android开发中,多线程下载是一项常见的任务...总结来说,Android多线程下载涉及到了Android线程模型、网络请求、文件I/O、同步机制、进度更新等多个核心知识点,通过合理的设计和实现,可以提升下载效率和用户体验。

    Android两个子线程之间的通信

    首先,理解Android线程模型至关重要。主线程,也称为UI线程,负责处理用户界面的更新和事件响应。为了不阻塞主线程,我们通常会在子线程中执行耗时任务。然而,当这些子线程需要与主线程交互,例如更新UI或共享数据...

    Android开发中的多线程编程技术

    二、Android中的线程模型 1. Handler-Looper-Messenger:通过Handler、Looper和Message对象在主线程和工作线程之间传递消息,进行同步或异步通信。 2. AsyncTask:轻量级的多线程解决方案,适合短时间的后台任务,...

    android 线程入门教程

    根据提供的文件信息,我们可以提炼出Android线程入门教程的相关知识点。本教程主要面向Android开发新手,着重介绍Android中的线程机制,包括UI线程模型以及线程间通信的方法。 知识点一:Android UI单线程模型 ...

    Android多线程操作

    理解并熟练运用各种线程模型、同步机制以及通信方式,能帮助开发者构建出更加高效和稳定的Android应用。通过分析提供的文件名,我们可以推测这个实例可能是关于如何在后台线程加载数据并在UI线程更新进度的一个教程...

    Android 线程+View的使用

    理解这两种方式的关键在于掌握Android的消息机制和线程模型。主线程(也叫UI线程)负责处理用户交互和更新UI,而子线程则用于执行耗时任务。Post方式直接在View上操作,Handler方式通过消息队列进行间接通信。在实际...

    android 线程详解 各种经典 完整代码

    在Android开发中,线程管理是一项至关重要的技能,因为它直接影响到应用的性能和用户体验。本文将深入探讨Android线程的概念、类型...在实际项目中,根据任务特性和需求选择合适的线程模型,能显著提高应用的用户体验。

Global site tag (gtag.js) - Google Analytics