文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>一切为了更贴近系统—Android中的线..

一切为了更贴近系统—Android中的线..

时间:2010-10-27  来源:凌晨的太阳

 

 

这篇文章将讨论Android应用程序中使用的线程模型,并讨论如何确保应用程序最佳的UI呈现(通过创建工作者线程来处理耗时的操作,而不是在主线程里处理)。这篇文章还将阐述与运行在主线程中的UI组件交互的API以及创建托管的工作者线程的API。

UI线程

当应用程序启动后,系统创建了一个叫做“main”的线程。主线程,也叫UI线程,非常重要,因为它负责分发事件给构件,包括绘制事件。也是这个线程,在这里才能与Android UI工具包中的组件进行交互。

例如,当你触摸屏幕上的一个按钮时,UI线程会分发一个触摸事件给构件,然后,构件会设定自己为被按下的状态,并抛出一个显示无效的请求给事件队列。UI线程队列请求并通知构件绘制自己。

单线程模型会导致性能低下,除非你的程序很好地实现。特别是,当所有的操作都在单一的线程中进行,耗时的操作(如网络访问、数据查询)会阻塞UI。在耗时操作执行时,没有任何事件可以分发,包括绘制的事件。从用户的视觉来看,应用程序被挂起了。更糟糕的是,如果UI线程阻塞超过一定的时间(现在大约是5秒钟),系统会给用户呈现一个糟糕的“应用程序无响应”(ANR)对话框。

如果你想看这有多糟糕,你可以写一个简单的应用程序,在一个Button的OnClickListener函数中调用Thread.sleep(2000)。按钮在回到它正常状态之前,保持被按下的状态2秒钟。当这种情况发生时,用户很容易认为应用程序慢。

总之,对于应用程序UI的响应性来说,保证UI线程不被阻塞是至关重要的。如果你有耗时的操作,你应该确保在另外的线程(后台或工作者线程)中执行。

下面有一个例子,点击事件处理函数中,从网络上下载一个图片,并显示到ImageView上:

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      Bitmap b = loadImageFromNetwork();
      mImageView.setImageBitmap(b);
    }
  }).start();
}

乍一看,这段代码能很好的解决你的问题,因为它不会阻塞UI线程。遗憾的是,它违背了UI的单线程模型:Android UI工具包不是线程安全的,必须在UI线程中进行操作。在上面的代码片段里,ImageView是在工作者线程中操作的,因此,这会引发可拍的问题。跟踪和修正这些Bug可能是困难且耗时的。

Android提供了一些方法,能在其它线程中访问UI线程。你可能对其中的一些已经很熟悉了,但这里是一份较为全面的列表:

·         

排行榜 更多 +
翌日波奇狗的历险记手机版下载

翌日波奇狗的历险记手机版下载

休闲益智 下载
怪兽远征安卓版下载

怪兽远征安卓版下载

角色扮演 下载
谷歌卫星地图免费版下载

谷歌卫星地图免费版下载

生活实用 下载