Android 进程和线程详解
作者:网络转载 发布时间:[ 2013/5/14 13:43:47 ] 推荐标签:
线程
Android系统启动某个应用后,将会创建一个线程来运行该应用,这个线程成为“主”线程。主线程非常重要,这是因为它要负责消息的分发,给界面上相应的UI组件分发事件,包括绘图事件。这也是应用可以和UI组件(为android.widget和android.view中定义的组件)发生直接交互的线程。因此主线程也通常称为用户界面线程(UI线程)。
Android系统不会主动为应用程序的组件创建额外的线程。运用在同一进程中所有程序组件都在UI线程中初始化,并使用UI线程来分发对这些程序组件的系统调用。由此可见,响应系统回调函数(比如onKeyDown() 响应用户按键或者某个生命周期回调函数)的方法总是使用UI线程来运行。
比如,当用户触摸屏幕上某个按钮时,你的应用中的UI线程将把这个触摸事件发送到对应的UI小组件,然后该UI小组件设置其按下的状态并给事件队列发送一个刷新的请求,之后UI线程处理事件队列并通知该UI小组件重新绘制自身。
当你的应用中响应用户事件时需要完成一些费事的工作时,这种单线程工作模式可能会导致非常差的用户响应性能。尤其是如果所有的工作都在UI线程中完成,比如访问网络,数据库查询等费时的工作将会阻塞UI线程。当UI线程被阻塞时,无法分发事件,包括绘图事件。此时从用户的角度来看,该应用看起来不再有响应。更为糟糕的是,如果UI线程阻塞超过几秒钟(目前为五秒),系统将给用户显示的“应用程序无响应”(ANR)对话框。用户可能会选择退出你的应用,更为甚者如果他们感觉很不满意也会选择卸载你的应用。
此外,Android的UI组件包不是“线程安全”的,因此你不能走工作线程中调用UI组件的方法,所有有关UI的操作必须在UI线程中完成,因此下面为使用UI单线程工作线程的两个规则:
1. 永远不要阻塞UI线程。
2. 不要在非UI线程中操作UI组件。
工作线程
由于Android使用单线程工作模式,因此不阻塞UI线程对于应用程序的响应性能至关重要。如果在你的应用中包含一些不是一瞬间能完成的操作的话,你应用使用额外的线程(工作线程或是后台线程)来执行这些操作。
比如下面示例,在用户点击某个按钮后,启动一个新线程来下载某个图像然后在ImageView中显示:
[java] view plaincopyprint?
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
private Bitmap loadImageFromNetwork(String string) {
// TODO Auto-generated method stub
return null;
}
}).start();
}
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
private Bitmap loadImageFromNetwork(String string) {
// TODO Auto-generated method stub
return null;
}
}).start();
}
乍一看,这段代码应该很好的完成工作,因为它创建了一个新线程来完成网络操作。然而它违法了上面说的第二个规则:不要在非UI线程中操作UI组件。在这段代码中的工作线程中而不是在UI线程中,直接修改ImageView,这将导致一些不可以预见的后果,常常导致发现此类错误捕捉异常困难和费时。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11