[转]Android:异步处理之AsyncTask的应用(二)
- 2014-11-07
- 既然UI老人家都这么忙了,我们这些开发者肯定不能不识趣的去添乱阻塞UI线程什么的,否则UI界面万一停止响应了呢——这不是招骂的节奏么?!所以我们知道用Handler+Thread的方法,在子线程中处理耗时的任务,任务完成后通过Handler通知UI主线程更新UI界面,皆大欢喜有木有。
可是这样,还是有某些人觉得用Handler+Thread的代码会比较繁琐,当然这个某些人里面包括我们伟大的谷歌。所以AsyncTask(异步任务)在Android 1.5中横空出世;相对于Handler来说,由于比较好的封装,AsyncTask显得更加轻量级一点,适用于简单的异步处理;当然使用起来也比较简洁,果然是谷歌的亲儿子!概述AsyncTask是一个抽象类,通常是被继承的命。AsyncTask的内部会维持一个静态的线程池,每个后台任务自然也会被提交到线程池中运行,同时也使用Handler+Thread的机制来调用AsyncTask的各个回调方法;回调方法是在主线程运行的,所以该干什么我们都懂(~ o ~)~zZ(赶紧跟UI界面套近乎呀)。我们知道AsyncTask<Params, Progress, Result>是抽象类,我们可以在这里面看出它支持三种泛型:1、Params:我们的AsyncTask要开始干活时,我们给他的输入的参数的类型,也就是传递给后台的参数2、Progress:AsyncTask向我们报告它干活进度的参数类型,举个例子就是下载进度的百分比3、Result:后台执行任务完成,返回的结果的参数类型如果某个泛型我们不需要指定,我们可以大大方方的指定Void,没事AsyncTask不会伤心滴。当然谷歌也帮我们将AsyncTask的后台任务运行的五种状态,分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务。每种状态在AsyncTask中各有相应的回调方法。1、准备运行:onPreExecute(),在任务开启时该回调方法立即在UI线程中被调用,同时也是在执行后台耗时操作前被调用;通常该方法用于完成一些初始化工作,比如在界面上显示进度条等。2、正在后台运行:doInBackground(Params...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用,重写该方法就是后台线程将要完成的耗时任务;由于是由后台线程调用,所以我们不能直接在这里更新UI界面,应该使用publishProgress(Progress...)触发回调方法onProgressUpdate(Progress...)进行进度更新;任务计算的结果必须由该函数返回,并被传递到onPostExecute()中。3、进度更新:onProgressUpdate(Progress...),在doInBackground()中调用publishProgress()方法更新任务的执行进度,将会在主线程中触发该方法,一般用于动态地显示一个进度条。4、完成后台任务:onPostExecute(Result),当doInBackground()完成后,系统会自动调用onPostExecute()方法,并将doInBackground()的返回值传递给该方法。5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用。案例参考代码:复制代码public class MainActivity extends ActionBarActivity implements OnClickListener{private Button startdownload;private ProgressBar probar;private TextView tv;private DownTask task;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);startdownload = (Button) findViewById(R.id.startdownload);probar = (ProgressBar) findViewById(R.id.probar);tv = (TextView) findViewById(R.id.tv);startdownload.setOnClickListener(this);}@Overridepublic void onClick(View v) {task = new DownTask();//同一个AsyncTask的execute只能调用一次task.execute("输入参数,可为空");//调用execute后将会回调onPreExecute方法}class DownTask extends AsyncTask<String, Integer, String>{@Override//该方法非在主线程运行,可进行耗时操作,不可更新UI界面,其他方法为主线程运行protected String doInBackground(String... params) {//params为execute输入的参数for(int i = 1; i <= 100; i++){try {//模拟下载操作Thread.sleep(333);publishProgress(i);//传递参数i并触发onProgressUpdate回调方法} catch (InterruptedException e) {e.printStackTrace();}}String result = "任务已完成";return result;//将调用onPostExecute,并将result传给该回调方法}@Overrideprotected void onPreExecute() {//该回调方法执行完毕后,将会调用doInBackgroundprobar.setMax(100);probar.setProgress(0);tv.setText("开始下载");}@Overrideprotected void onPostExecute(String result) {//doInBackground结束后回调该方法,结束。Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();tv.setText("下载完成");}@Overrideprotected void onProgressUpdate(Integer... values) {//通知UI界面更新probar.setProgress(values[0]);}}}复制代码布局文件:复制代码<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><Buttonandroid:id="@+id/startdownload"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="开始下载"/><ProgressBarandroid:id="@+id/probar"android:layout_width="match_parent"android:layout_height="wrap_content"style="@android:style/Widget.ProgressBar.Horizontal"/><TextViewandroid:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#000000"android:textSize="20sp"/></LinearLayout>复制代码代码讲解:1、点击Button后先实例化一个AsyncTask的继承子类,此时将会创建一个task。接下来变执行execute(params)方法启动异步任务。(同一个AsyncTask的实例只能执行execute一次,多次执行会抛出错误)。2、在execute()被执行后,将会触发onPreExecute()回调方法,设置进度条的初始属性。在onPreExecute()执行完毕后,将会在后台线程开始执行doInBackground(params),该方法接收execute传入的参数,进行耗时操作,这里是模拟网络文件下载任务。3、doInBackground()在后台线程运行中,如果需要与UI主线程交互更新进度,可以调用publishProgress(values)方法,将会触发位于UI主线程运行的onProgressUpdate(values)的回调方法,代码中在这里更新进度条的进度。4、 当后台任务执行完成后,调用onPostExecute(Result),传入的参数是doInBackground()中返回的对象。注意事项1、不要在同一个AsyncTask实例中多次执行execute(),正确的方法是new一个AsyncTask执行一次execute()。2、耗时任务一定要在doInBackground()中处理,不要在其他回调方法中处理耗时任务以免引起UI主线程的阻塞。3、不要再doInBackground()中更新UI界面,应该通过publishProgress()调用回调方法更新UI。4、onCancelled()只能触发AsyncTask的cancel()方法,并无法取消正在线程池运行的线程任务,但可以通过标志位来停止线程任务。5、在不同的android版本中,AsyncTask多任务运行,有些是可以并行有些则是顺序执行,不过在高版本Android中,可以通过指定参数设置线程池执行规则。6、AsyncTask适合处理短时间的操作,长时间的操作,比如下载一个很大的视频,这就需要你使用自己的线程来下载,不管是断点下载还是其它的。
[转]Android:异步处理之AsyncTask的应用(二)的更多相关文章
- Java基础知识强化之网络编程笔记15:Android网络通信之 Android异步任务处理(AsyncTask使用)
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的 ...
- Android异步任务处理框架AsyncTask源代码分析
[转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比方最常见的网络请求).遇到这样的问题.我 ...
- android异步加载AsyncTask
http://blog.csdn.net/abc5382334/article/details/17097633 http://keeponmoving.iteye.com/blog/1515611 ...
- Android线程管理之AsyncTask异步任务
前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 线程管理相 ...
- Android(java)学习笔记149:Android线程形态之 AsyncTask (异步任务)
1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...
- Android 消息异步处理之AsyncTask
Android提供了异步处理消息的方式大致有两种,第一种是handler+Thread,之前已经对于这种方式做过分析,第二种就是AsyncTask,这是Android1.5提供的一种轻量级的工具类,其 ...
- Android异步处理系列文章四篇之四 AsyncTask的实现原理
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android:异步处理之AsyncTask的应用(二)
前言 在上一篇文章中<Android:异步处理之Handler+Thread的应用(一)>,我们知道Android的UI主线程主要负责处理用户的按键事件.用户的触屏事件以及屏幕绘图事件等: ...
随机推荐
- hdu 1498 50 years, 50 colors(二分匹配_匈牙利算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1498 50 years, 50 colors Time Limit: 2000/1000 MS (Ja ...
- Appium环境搭建说明(包括报错处理)
Appium环境搭建说明 一.环境配置 前提是windows系统已安装以下软件: 1.jdk 我装的是1.8.0 2.android-sdk 3.python,3.4-3.6 5.Node.js,v8 ...
- 关于ORA-04091异常的出现原因,以及解决方案
问题分析 在Oracle中执行DML语句的时候是需要显示进行提交操作的.当我们进行插入的时候,会触发触发器执行对触发器作用表和扩展表的种种操作,但是这个时 候触发器和插入语句是在同一个事务管理中的,因 ...
- 查找网页元素对应的js代码
按F12打开调试窗口,切换到Sources选项卡,最右边的Event Listener Breakpoints里勾选Mouse下的mouseover即可,当鼠标移动到图片上时触发mouseover事件 ...
- CSU 1424 Qz’s Maximum All One Square
原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1424 逐渐找到做这种题的感觉了. 二分法.g[i][j]存储坐标(i, j)的值,s[i ...
- Linux文件系统的详解
这里以 EXT2 文件系统为例 在Linux下,一个磁盘的最前面是MBR,大小为512Byte 在每一个分区下,第一部分是boot sector,接下来是super block,再接下来是inode, ...
- C++输入与输出
1 概述 C和C++都没有将输入和输出建立在语言中,C++将输入输出的解决方案放在类库中(由头文件iostream和fstream中定义的类) C++程序把输入和输出看作字节流.流充当了程序和流源流目 ...
- Robot Framework + Selenium2Lib
Robot Framework + Selenium2Lib 最近一段时间,公司在推行自动化测试流程,本人有幸参与了自定义通用控件的关键字封装和脚本辅助编写.数据驱动管理.测试用例执行管理等一系列工具 ...
- laravel windows安装(composer)
1.安装composer参考windows 安装tp5 composer方式 2.先配置好本地虚拟域名,在cmd里面切换到网站根目录 ... 3.安装成功之后,在浏览器输入已配置的虚拟域名我的是,la ...
- Linq简单使用
简单使用 from子查询 关联多个数据源 分组 let 子句 查询对象(上例中为list变量)为IEnumerable<T>或IQueryable<T>类型 查询返回结果同样为 ...