Handler和AsyncTask的使用及优缺点比较
2017-03-30 23:48
225 查看
AsyncTask和Handler都是为了不阻塞主线程而执行异步操作的类。
正式开始讨论Handler和AsyncTask之前,有几个Android的规则要强调一次:
1.只能在UI线程中访问界面;
2.UI线程被阻塞(大概5秒钟)后会导致ANR(Application Not Responding)错误。
简单说一下Handler机制,这涉及到Handler、Looper和HandlerThread
Looper轮询器:Looper中带有一个MessageQueue(消息队列),Looper负责轮询此消息队列,将Message(消息)取出后交由Handler来处理。
HandlerThread消息循环线程:即Handler执行的线程,此线程大部分时间都在运行Looper.loop()方法,即消息轮询方法;它会通过getLooper方法返回一个Looper对象,Handler需要使用此对象作为参数创建对象。
Handler处理者:负责接收消息、发送消息和处理消息(handleMessage方法),我们需要重载handleMessage方法来处理各种消息。
Handler的一些方法:
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
它直接继承Object,为我们体用了三个泛型并重载了几个方法
三种泛型:
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的进度。
Result 后台执行任务最终返回的结果,比如String。
当一个异步任务被执行的时候,需要经历四步:
onPreExecute():-----在UI线程中执行,它会在异步任务开始前执行,一般用来设置任务参数;
doInBackground(): ----接收任务参数,执行异步任务,返回结果传给第四步;执行途中,它还可以调用publishProgress方法来通知UI线程当前执行的进度; (只有它在子线程中执行,其他方法都在UI线程中执行)
onProgressUpdate(): ----当publishProgress被调用后,刷新任务进度。
onPostExecute():----当后台的异步任务完成后,它会在UI线程中被调用,并获取异步任务执行完成的结果。
有必要的话你还得重写以下这三个方法,但不是必须的:
onProgressUpdate(Progress…) -----在UI线程中执行,刷新任务进度。
onCancelled() ------用户调用取消时,要做的操作
使用AsyncTask类,以下是几条必须遵守的准则:
§ Task的实例必须在UI thread中创建;
§ execute方法必须在UI thread中调用;
§ 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
§ 该task只能被执行一次,否则多次调用时将会出现异常;
封装一个AsyncTask进行图片加载示例:
更多:http://blog.csdn.net/LogicTeamLeader/article/details/51165375
正式开始讨论Handler和AsyncTask之前,有几个Android的规则要强调一次:
1.只能在UI线程中访问界面;
2.UI线程被阻塞(大概5秒钟)后会导致ANR(Application Not Responding)错误。
Handler:
主要接收子线程发送的数据,然后用此数据配合主线程更新UI简单说一下Handler机制,这涉及到Handler、Looper和HandlerThread
Looper轮询器:Looper中带有一个MessageQueue(消息队列),Looper负责轮询此消息队列,将Message(消息)取出后交由Handler来处理。
HandlerThread消息循环线程:即Handler执行的线程,此线程大部分时间都在运行Looper.loop()方法,即消息轮询方法;它会通过getLooper方法返回一个Looper对象,Handler需要使用此对象作为参数创建对象。
Handler处理者:负责接收消息、发送消息和处理消息(handleMessage方法),我们需要重载handleMessage方法来处理各种消息。
Handler的一些方法:
post(Runnable) postAtTime(Runnable,long) postDelayed(Runnable,long) sendEmptyMessage(int) sendMessage(Message) sendMessageAtTime(Message,long) sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
AsyncTask
AsyncTask是一个辅助类,就是为了将Handler、Thread等封装为一个异步执行框架,方便调用。主要目的是为了“在其他线程中执行一个耗时操作,并随时报告执行进度给UI线程,执行完成后将结果报告给UI线程”。它直接继承Object,为我们体用了三个泛型并重载了几个方法
三种泛型:
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的进度。
Result 后台执行任务最终返回的结果,比如String。
当一个异步任务被执行的时候,需要经历四步:
onPreExecute():-----在UI线程中执行,它会在异步任务开始前执行,一般用来设置任务参数;
doInBackground(): ----接收任务参数,执行异步任务,返回结果传给第四步;执行途中,它还可以调用publishProgress方法来通知UI线程当前执行的进度; (只有它在子线程中执行,其他方法都在UI线程中执行)
onProgressUpdate(): ----当publishProgress被调用后,刷新任务进度。
onPostExecute():----当后台的异步任务完成后,它会在UI线程中被调用,并获取异步任务执行完成的结果。
有必要的话你还得重写以下这三个方法,但不是必须的:
onProgressUpdate(Progress…) -----在UI线程中执行,刷新任务进度。
onCancelled() ------用户调用取消时,要做的操作
使用AsyncTask类,以下是几条必须遵守的准则:
§ Task的实例必须在UI thread中创建;
§ execute方法必须在UI thread中调用;
§ 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
§ 该task只能被执行一次,否则多次调用时将会出现异常;
封装一个AsyncTask进行图片加载示例:
public class NetCacheUtils { private static final String TAG = "NetCacheUtils"; private ImageView imageView; public void getBitmapFromNet(ImageView imageView, String url) { //2.执行 :异步加载类对象.excute(Params... params); //异步下载图片 new BitmapTask().execute(imageView, url); } /** * 1.自定义异步加载类 * @Params Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。 * @Params Progress:后台任务子线程执行的百分比 * @Params Result:后台执行任务最终返回结果。和doInBackground()方法的返回值类型保持一致。 */ class BitmapTask extends AsyncTask<Object, Void, Bitmap> {//Params,Progress,Result private ImageView imageView; private String url; //这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。 @Override protected void onPreExecute() { super.onPreExecute(); } /** * 后台线程执行异步任务,将result告知UI线程。 * 返回值类型和Result保持一致。参数:若无就传递Void;若有,就可用Params */ @Override protected Bitmap doInBackground(Object... params) { imageView = (ImageView) params[0]; url = (String) params[1]; imageView.setTag(url);//给当前ImageView打标签 //使用url下载图片 Bitmap bitmap = download(url); return bitmap; } /** * 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回 * 参数:和Result保持一致 */ @Override protected void onPostExecute(Bitmap result) { if (result != null) { //给ImageView设置图片 //由于ListView的重用机制,导致某个item有可能展示它所重用的那个item的图片, 导致图片错乱 //解决方案:确保当前设置的图片和当前显示的imageview完全匹配 String url = (String) imageView.getTag();//获取和当前ImageView绑定个url if (this.url.equals(url)) {//判断当前下载的图片的url是否和imageView的url一致, 如果一致,说明图片正确 imageView.setImageBitmap(result); System.out.println("从网络下载图片啦!!!"); } } } } }
更多:http://blog.csdn.net/LogicTeamLeader/article/details/51165375
相关文章推荐
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler两种异步方式实现原理和优缺点比较
- (Android实战)AsyncTask和Handler两种异步方式实现原理和优缺点比较
- Android Asynctask与Handler的比较,优缺点区别,Asynctask源码
- AsyncTask和Handler的优缺点比较
- AsyncTask 和Handler 的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- AsyncTask和Handler的优缺点比较
- Android Asynctask与Handler的比较,优缺点区别,Asynctask源码
- AsyncTask和Handler的优缺点比较(更新线程的问题总结
- AsyncTask和Handler的优缺点比较