注:本文编写来自于官网,并加上了作者自己的部分心得。
前言
本文章主要简单介绍主线程,并且在使用的过程中如何避免ANR异常。
UI线程基本介绍
当一个应用启动时,系统会为该应用创建一个名为“主线程(或UI 线程)”的执行线程。此线程非常重要,作用如下:
1.它负责将事件分派给相应的用户界面小部件,其中包括绘图事件。
2。它也是应用与 Android UI 工具包组件(来自 android.widget 和 android.view 软件包的组件)进行交互的线程。
主线程有时。
我们知道android有4大组件(activity,service,contentprovider,broadcast),这4大组件均在UI线程中实例化,并且对每个组件的系统调用均由该线程进行分派。 因此,响应系统回调的方法(例如,报告用户操作的 onKeyDown() 或生命周期回调方法)始终在进程的 UI 线程中运行。也就是说这4大组件均在主线程中运行。所以大家在写代码的时候不要非常耗时间的操作以防发生ANR异常。如果引起用户不满,他们可能就会决定退出并卸载此应用。
此外,Android UI 工具包并非线程安全工具包。因此,您不得通过工作线程操纵 UI,而只能通过 UI 线程操纵用户界面。 因此,Android 的单线程模式必须遵守两条规则:
1.不要阻塞 UI 线程
2.不要在 UI 线程之外访问 Android UI 工具包
请大家无比将这二条牢记于心。
错误案例和解决办法
根据上述介绍,要保证应用 UI 的响应能力,关键是不能阻塞 UI 线程。 如果执行的操作不能很快完成,则应确保它们在单独的线程(“后台”或“工作”线程)中运行。
错误案例:
以下代码演示了一个点击侦听器从单独的线程下载图像并将其显示在 ImageView 中:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}
乍看起来,这段代码似乎运行良好,但是会抛出一场。因为它违反了单线程模式的第二条规则:不要在 ui 线程之外访问 android ui 工具包 而上面代码从工作线程(而不是 UI 线程)修改了 ImageView。
解决办法:
1.getActivity().runOnUiThread(Runnable)
2.View.post(Runnable)
3.View.postDelayed(Runnable, long)
4.new Handler(Looper.getMainLooper()).post(Runnable);
5.handler处理
6.new Handler().post(Runnable);
正确案例:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap =
loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
上述实现属于线程安全型:在单独的线程中完成网络操作,而在 UI 线程中操纵 ImageView。
结尾
好了就讲到这里吧,如果觉的有收获,请点个赞吧。