Android攻城狮AsyncTask
构建AsyncTack子类的参数 AsyncTask<Params,Progress,Result>是一个抽象类,通常用于被继承,继承AsyncTask需要指定如下三个泛型参数: params:启动任务时输入参数的类型。 progress:后台任务执行中,返回进度值的类型。 Result:后台执行任务完成后,返回结果的类型。 ------------------------ 如何构建AsyncTask子类的回调方法? 一个完整的AsyncTask通常需要指定如下几个方法: 1. doInBackground:这是AsyncTask子类所必须要重写的方法,异步执行后台线程将要完成的任务。我们所有的耗时操作都将在这个方法中进行操作。 2. onPreExecute:执行后台耗时操作之前被调用,通常是用户完成一些初始化操作。 3. onPostExecute:当doInBackground()完成后,系统会自动调用此方法,并将doInBackground()返回的值传给该方法,也就是展示处理完成的结果。 4. onProgressUpdate:在doInBackground()方法中调用publishProgrsss()更新任务的执行进度后,就会触发该方法(必须先调用publishProgrsss()),就可以知道当前耗时操作的完成进度。 ---------------------------------- 额外补充: 1. 注意这里的例子继承的是 AsyncTask<Void,Void,Void>,需要带上三个泛型,定义Void泛型要注意V是大写。。。 2. 执行顺序:onPrRreExecute() --> doInBackground() --> onProgressUpdate() --> onPostExecute()。
AsyncTask<String,Void,Bitmap>三个参数分别为:url类型,进度值类型,返回值类型。 这里的例子暂时不设置进度值,url设置为String类型,又因为我们加载的是一张Bitmap,所以返回的参数类型设置为 Bitmap。 1. doInBackground(String...params)传进来的是一个可变长数组,也就是说,我们可以传进不止一个参数(通过execute()传进来),这些参数依次存在于这个数组中。现在只有一个参数,所以只要写个params[0]取出对应的URL即可。 2. 定义一个Bitmap,也就是我们所要获取的Bitmap。 3. 定义一个访问网络的URLconnection,也就是一个网络连接对象connection。 4. 定义一个InputStream,用于获取数据的输入流。 5. 初始化connection:connection = new URL(url).openConnection();这里需要自行导入jar包:import java.net.URL; 另外需要try-catch包围。 6. 获取输入流:is = connection.getInputStream(); 7. 对输入流进行包装:BufferedInputStream bis = new BufferedInputStream(is); 8. 通过decodeStream()将输入流解析成 Bitmap:bitmap = BitmapFactory.decodeStream(bis); 9. 关闭输入流、返回 bitmap。
1 //Asynctask加载网络图片 2 //使用ProgressBar 和ProgressDialog提示下载的进度 3 4 public class ImageTest extends Activity { 5 private ImageView imageView; 6 private ProgressBar progressBar;// 方式一:对话框提示进度 7 String URL = "http://p4.so.qhimgs1.com/sdr/1228_768_/t01f7ed810efbfe800a.jpg"; 8 ProgressDialog dialog;// 方式二:对话框提示进度 9 MyAsynctask1 task; 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 // TODO Auto-generated method stub 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.image); 16 imageView = (ImageView) findViewById(R.id.image); 17 progressBar = (ProgressBar) findViewById(R.id.bar); 18 19 dialog = new ProgressDialog(this); 20 dialog.setTitle("提示信息:"); 21 dialog.setMessage("laoding...."); 22 dialog.setProgressStyle(dialog.STYLE_HORIZONTAL); 23 24 MyAsynctask1 task = new MyAsynctask1(); 25 task.execute(URL); 26 27 } 28 29 // 不等进度条满就后退再执行,会发现后面执行的进度条迟迟没有响应, 30 // 令AsyncTask的生命周期和Activity或者Fragment的生命周期保持一致就可以了。 31 @Override 32 protected void onPause() { 33 // TODO Auto-generated method stub 34 super.onPause(); 35 if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) { 36 task.cancel(true); 37 // cancel()只是将对应的task标记为cancel状态,并不是真正取消线程执行 38 } 39 } 40 41 // params:启动任务时输入参数的类型。 42 // progress:后台任务执行中,返回进度值的类型。 43 // Result:后台执行任务完成后,返回结果的类型。 44 45 // 2. 执行顺序:onPrRreExecute() --> doInBackground() --> onProgressUpdate() --> 46 // onPostExecute()。 47 class MyAsynctask1 extends AsyncTask<String, Integer, Bitmap> { 48 @Override 49 // 1.执行后台耗时操作之前被调用,通常是用户完成一些初始化操作。 50 protected void onPreExecute() { 51 // TODO Auto-generated method stub 52 super.onPreExecute(); 53 // 显示进度条 54 progressBar.setVisibility(View.VISIBLE); 55 dialog.show(); 56 } 57 58 // 4.当doInBackground()完成后,系统会自动调用此方法,并将doInBackground()返回的值传给该方法,也就是展示处理完成的结果。 59 @Override 60 protected void onPostExecute(Bitmap result) { 61 // TODO Auto-generated method stub/ 62 super.onPostExecute(result); 63 progressBar.setVisibility(View.GONE);// 消失进度条 64 dialog.dismiss(); 65 imageView.setImageBitmap(result); 66 67 } 68 69 // 2. 70 // doInBackground:这是AsyncTask子类所必须要重写的方法,异步执行后台线程将要完成的任务。我们所有的耗时操作都将在这个方法中进行操作。 71 @Override 72 protected Bitmap doInBackground(String... params) { 73 // TODO Auto-generated method stub 74 75 // 从params中取出参数值,传给url 76 String url = params[0]; 77 // 初始化参数 78 Bitmap bitmap = null; 79 URLConnection connection; 80 InputStream inputStream; 81 82 try { 83 connection = new URL(url).openConnection(); 84 inputStream = connection.getInputStream();// 获取输入流 85 BufferedInputStream bis = new BufferedInputStream(inputStream); 86 Thread.sleep(5000);// 睡3秒 87 // 通过decodeStream()解析输入流 88 bitmap = BitmapFactory.decodeStream(bis); 89 inputStream.close(); 90 bis.close(); 91 92 } catch (IOException e) { 93 // TODO Auto-generated catch block 94 e.printStackTrace(); 95 } catch (InterruptedException e) { 96 // TODO Auto-generated catch block 97 e.printStackTrace(); 98 } 99 // 模拟进度更新 100 for (int i = 0; i < 100; i++) { 101 if (isCancelled()) { 102 break; 103 } 104 publishProgress(i); 105 106 } 107 return bitmap; 108 } 109 110 // 3.在doInBackground()方法中调用publishProgrsss()更新任务的执行进度后,就会触发该方法(必须先调用publishProgrsss()),就可以知道当前耗时操作的完成进度。 111 @Override 112 protected void onProgressUpdate(Integer... values) { 113 // TODO Auto-generated method stub 114 super.onProgressUpdate(values); 115 if (isCancelled()) { 116 return; 117 118 } 119 dialog.setProgress(values[0]); 120 progressBar.setProgress(values[0]); 121 } 122 123 } 124 125 }
反复执行上一节课的异步加载,而且是不等进度条满就后退再执行,会发现后面执行的进度条迟迟没有响应,为什么呢?这并非bug,而是 AsyncTask 所实行的一种机制。AsyncTask的底层是通过线程池去作用的。当一个线程没有完成的时候,后面的线程就无法开始。我们上一节课用了for()循环去执行进度条 的更新操作,必须等到for()循环结束后才会执行下一个Task。 --------- 那么,如何去解决这样的问题呢? 很简单,令AsyncTask的生命周期和Activity或者Fragment的生命周期保持一致就可以了。 回到ProgressBar,重写onPause(),在Activity执行onPause()的时候,对AsyncTask进行判断: 如果AsyncTask不为空且处于Running状态,我们就要取消该线程:protected void onPause() {super.onPause();if(mTask!=null && mTask.getStatus()==AsyncTask.Status.RUNNING){mTask.cancel(true);}} cancle()方法只是将对应的AsyncTask标记为cancel状态,并不是真正地取消线程的执行。 另外,我们在Java中也是没办法直接粗暴地停止一个线程,我们必须要等一个线程执行完毕之后才能继续其他线程的操作。 -------------- 那要如何快速停止线程呢? 1. 在onPause()中标记取消状态:mTask.cancel(true); 既然我们已经标记了cancel状态,那么可以在AsyncTask中监测这样的改变,一旦当前状态改为cancelled,我们就要跳出循环,立刻结束当前操作,从而结束整个线程逻辑。 2. 在doInBackground()方法的for()循环内添加isCancelled()对线程的状态进行判断: if(isCancelled())break; 3. 同理,在onProgressUpdate()方法中也做类似的处理: if(isCancelled())return; 通过如上操作,我们就能快速停止当前线程,将处理权交给下一个AsyncTask。
1 public class ProgressBarTest extends Activity { 2 3 ProgressBar progressBar; 4 MyAsycnTask2 task; 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 // TODO Auto-generated method stub 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.progressbar); 10 progressBar = (ProgressBar) findViewById(R.id.progressBar1); 11 12 task = new MyAsycnTask2(); 13 task.execute(); 14 } 15 16 @Override 17 protected void onPause() { 18 // TODO Auto-generated method stub 19 super.onPause(); 20 if (task!=null&&task.getStatus()==AsyncTask.Status.RUNNING) { 21 task.cancel(true);//cancel()只是将对应的task标记为cancel状态,并不是真正取消线程执行 22 } 23 } 24 25 class MyAsycnTask2 extends AsyncTask<Void, Integer, Void> { 26 27 @Override 28 protected void onProgressUpdate(Integer... values) { 29 // TODO Auto-generated method stub 30 // 获取进度更新值 31 super.onProgressUpdate(values); 32 if (isCancelled()) { 33 return; 34 } 35 progressBar.setProgress(values[0]); 36 } 37 38 @Override 39 protected Void doInBackground(Void... params) { 40 // TODO Auto-generated method stub 41 42 // 模拟进度更新 43 for (int i = 0; i < 100; i++) { 44 if (isCancelled()) { 45 break; 46 } 47 publishProgress(i); 48 try { 49 Thread.sleep(300); 50 } catch (InterruptedException e) { 51 // TODO Auto-generated catch block 52 e.printStackTrace(); 53 } 54 } 55 return null; 56 } 57 } 58 }
转载于:https://www.cnblogs.com/my334420/p/6724539.html
Android攻城狮AsyncTask相关推荐
- 写给即将/正在找工作的Android攻城狮
写给即将/正在找工作的Android攻城狮 版权声明:转载必须注明本文转自严振杰的博客:http://blog.yanzhenjie.com 这段时间从北上广深杭不断传来一两个月找不到工作的消息,我一 ...
- Android攻城狮四大组件之Service
组件篇--Service 当Android系统内存不足的时候,会杀死优先级别较低的Activity,而基本上Service的优先级要高于Activity,所以程序中如果含有 Service,那么该程序 ...
- 写给即将正在找工作的Android攻城狮,算法太TM重要了
一.认识鸿蒙 鸿蒙 微内核是基于微内核的全场景分布式OS,可按需扩展,实现更广泛的系统安全,主要用于物联网,特点是低时延,甚至可到毫秒级乃至亚毫秒级. 鸿蒙OS实现模块化耦合,对应不同设备可弹性部署, ...
- Android攻城狮ListView
适配器: 数据适配器:把复杂的数据填充在指定的视图界面上ArrayAdapter 数组适配器 用于绑定格式单一的数据 数据源:可以是集合或数组 SimpleAdapter 简单适配器:用于绑定格式复杂 ...
- Android攻城狮Gallery和ImageSwitcher制作图片浏览器
使用Gallery 和 ImageSwitcher 制作图片浏览器 Gallery介绍 我们有时候在手机上或者PC上看到动态的图片,可以通过鼠标或者手指触摸来移动它,产生动态的图片滚动效果,还可以根据 ...
- Android攻城狮GestureDetector和GestureOverlayView
手势识别 可以通过以下两种方式实现: 1. 使用GestureDetector 2. 使用GestureOverlayView(属于线程的控件)手势交互过程(原理): 1. 触屏一刹那,触发 Moti ...
- Android攻城狮fragment
1 //1,fragment静态加载:MainActivity MainActivty1_2 Myfragment1 2 //2,fragment动态加载 :MainActivity Myfragme ...
- Android攻城狮ScrollView
ScrollView 滚动视图 滚动视图是指当前拥有很多内容,屏幕显示不完整时,需要通过滚动来显示完整的视图. ----------------------------- ScrollBar分两种: ...
- Android攻城狮ViewFlipper
使用ViewFlipper实现屏幕切换动画效果. ViewFlipper和ViewPager一样,都是Android自带的一个多页面管理控件,不同的是ViewPager是手动切换页面,而ViewFli ...
最新文章
- csgo国服文件转国际服务器,csgo国际服怎么转国服 csgo国际服转到国服方法介绍...
- ProtoBuf开发者指南
- 《Flex 第一步》
- BeetleX之Websocket协议分析详解
- c语言中字符占用的存储单元,C语言知识点第1章.doc
- python基础安装第三方(十三)
- VS 查看dll接口
- 【转】VS2010安装包制作
- 考虑云计算来降成本:良药或毒药?
- [大洋] Unity3D架构系列之- FSM有限状态机设计一至四
- 矩阵标准型的系数是特征值吗_数据分析基础:特征值和特征向量
- termux python turtle_如何在termux上安装Python的turtle库?
- 富滇银行 Windows7 无法使用U盾【证书信息读取失败,请选择正确的富滇银行网银证书!】 解决办法
- 深拷⻉浅拷⻉的区别?如何实现一个深拷贝?
- 世界电信日| 谈谈电信行业缘何牵线云计算?
- ai条码插件免安装_ai cs6条码插件 支持Illustrator cs6的条码生成脚本
- 大数据创业的未来到底在哪里?
- js利用tab键切换当前页面_JavaScript跳转到指定页面并且到指定的tab切换窗口
- python idle快捷键
- c语言实现小游戏-扫雷
热门文章
- threejs 特效 自定义发光围栏,发光墙体,闪烁动画
- Struts2编写自定义验证拦截敏感词汇(十二)
- 计算机无法启动安装程序,安装Win10系统提示安装程序无法正常启动怎么办
- python卡通滤镜_纯Python综合图像处理小工具(3)10种滤镜算法
- Centos7.x实现Cobbler无人值守安装
- 在用户计算机上的万维网客户程序是( ),在用户计算机上的万维网客户程序是()...
- GBase 8c 的安全特性
- ubuntu查看 固态硬盘位置_在Ubuntu(Linux)中启用固态硬盘(固态硬盘)TRIM | MOS86...
- php 继承 父类使用子类,在PHP中使用 来 实现子类和父类之间的继承 。
- MyBatis框架(二):多对一查询、一对多查询、ResultMap、动态SQL