Android UI线程和非UI线程
初学Android,记录下学习到的一些知识以备以后翻看。如有问题请指正。感谢。
UI线程
当你第一次启动一个Android程序的时候,一个被称为”main”的线程就被自动创建了。它被称为主线程或者UI线程,它是非常重要的因为负责分发事件给对应的widget,还包含画图的事件。主线程贯穿用户和Android widget的交互的整个过程。
系统不会为每个组件单独创建线程,在同一个进程里的UI组件都会在UI线程里实例化,系统对每一个组件的调用都从UI线程分发出去。
单线程模型导致Android程序低效,如果所有的工作都在UI线程,做一些比较耗时的工作比如访问网络或者数据库查询,都会阻塞UI线程,导致事件停止分发(包括绘制事件)。对于用户来说,应用看起来像是卡住了,更坏的情况是,如果UI线程blocked的时间太长(大约超过5秒),用户就会看到ANR(application not responding)的对话框。
Android的单线程模型有两条原则:
- 1.不要阻塞UI线程。
- 2.不要在UI线程之外访问Android UI toolkit
要避免在主线程中执行长时间的操作,你可能会使用额外的线程(后台线程或者工作线程)去执行操作。
Worker线程
根据单线程模型的两条原则,首先,要保证应用的响应性,不能阻塞UI线程,所以当你的操作不是即时的那种(not instantaneous),你应该把他们放进单另的线程中(叫做background或者叫worker线程)。
需要注意的是,为了防止从非UI线程访问UI组件会导致未定义和不能预料的行为,Android提供了一些方法,从其他线程访问UI线程。
AsyncTask :
Android1.5提供了一个公共类叫做AsyncTask,它简化了任务线程和主线程之间的通信。AsyncTask的目的就是帮助你管理线程。
例如下载图片并设置view展示时:
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask {
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
需要注意的是,AsyncTask通过它的子类才能使用。要记住,一个AsyncTask实例必须在主线程创建并且只能被执行一次。