时间:2015-05-29 来源:

Android应用AsyncTask处理机制详解及源码分析 【移动开发】

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处web切图报价,尊重分享成果】

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,web切图报价尊重分享成果】

1 背景 Android异步处理机制一直都是Android的一个核心,psd转html这里继续分析Android的另一个异步机制AsyncTask的原理.

AsyncTask的实例化只能在主线程,html切图Handler可以随意,wap前端外包只和Looper有关系.

3 Android5.1.1(API 22)AsyncTask源码分析 通过源码可以发现AsyncTask是一个抽象类web前端制作,是不是没有这个问题了吧?因为现在是顺序执行的.而且更劲爆的是现在的AsyncTask还直接提供了客户化实现Executor接口功能承接网页制作,如下:

到此是不是会好奇onProgressUpdate方法啥时候调运的呢?继续往下看可以发现handleMessage方法中的MESSAGE_POST_PROGRESS不就是回调我们UI Thread中的onProgressUpdate方法吗?那怎么样才能让他回调呢?追踪MESSAGE_POST_PROGRESS消息你会发现如下:

3-1 AsyncTask实例化源码分析 /** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. */ public AsyncTask() { mWorker = new WorkerRunnable<Params, e); } catch (ExecutionException e) { throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null); } } }; } 看见注释没有,符合w3c标准AsyncTask的实例化只能在UI线程中.然后整个构造函数就只初始化了两个AsyncTask类的成员变量(mWorker和mFuture).mWorker为匿名内部类的实例对象WorkerRunnable(实现了Callable接口),传入了mWorker作为形参(重写了FutureTask类的done方法).

6 AsyncTask总结 到此整个Android的AsyncTask已经分析完毕web前端制作,相信你现在对于AsyncTask会有一个很深入的理解与认识了.

2 实例演示 先看下使用AsyncTask模拟下载的效果图:

那怎么下手分析呢?很简单,web前端制作我们就依据上面示例的流程来分析源码承接网页制作,如下:

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处web切图报价,尊重分享成果】

接着可以看见,网站div+cssSerialExecutor是使用ArrayDeque这个队列来管理Runnable对象的符合w3c标准,如果我们一次性启动了很多个任务,符合w3c标准首先在第一次运行execute()方法的时候会调用ArrayDeque的offer()方法将传入的Runnable对象添加到队列的最后网页外包接活,第一次运行是null,然后调用scheduleNext()方法,div+css制作在这个方法中会从队列的头部取值承接网页制作,并赋值给mActive对象,承接网页制作然后调用THREAD_POOL_EXECUTOR去执行取出的取出的Runnable对象.之后如果再有新的任务被执行时就等待上一个任务执行完毕后才会得到执行web切图报价,所以说同一时刻只会有一个线程正在执行,web切图报价其余的均处于等待状态符合w3c标准, Progress, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; } 首先判断AsyncTask异步任务的状态web前端制作,当处于RUNNING和FINISHED时就报IllegalStateException非法状态异常.由此可以看见一个AsyncTask的execute方法只能被调运一次.接着看见17行onPreExecute();没有?看下这个方法源码,web前端制作如下:

public final AsyncTask<Params, Result> executeOnExecutor(Executor exec, Params... params) { ...... return this; } 可以看出,web切图报价在3.0以上版中AsyncTask已经不存在那个臭名昭著的Bug了符合w3c标准,所以可以放心使用了,符合w3c标准妈妈再也不用担心我的AsyncTask出Bug了.

看见没有网页外包接活,只是对线程做了优化处理和封装而已.

private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } } 在源码中可以看见web前端制作,SerialExecutor在AsyncTask中是以常量的形式被使用的,web前端制作所以在整个应用程序中的所有AsyncTask实例都会共用同一个SerialExecutor对象.

/** * Runs on the UI thread before {@link #doInBackground}. * * @see #onPostExecute * @see #doInBackground */ protected void onPreExecute() { } 空方法承接网页制作,而且通过注释也能看见,承接网页制作这不就是我们AsyncTask中第一个执行的方法吗?是的.

5 AsyncTask与Handler异步机制对比 前面文章也分析过Handler了web切图报价,现在把他们两拽一起来比较比较.具体如下:

private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; } 看见没有?依据返回值true与false回调AsyncTask的onPostExecute或者onCancelled方法.

mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked return postResult(doInBackground(mParams)); } }; 看见没有?在postResult()方法的参数里面,符合w3c标准我们可以看见doInBackground()方法.所以这验证了我们上面例子中使用的AsyncTask,首先在主线程执行onPreExecute方法,wap前端外包接着在子线程执行doInBackground方法web前端制作,所以这也就是为什么我们可以在doInBackground()方法中去处理耗时操作的原因了,div+css制作接着等待doInBackground方法耗时操作执行完毕以后将返回值传递给了postResult()方法.所以我们来看下postResult这个方法的源码承接网页制作, Integer, Boolean> { //如上三个泛型参数从左到右含义依次为: //1. 在执行AsyncTask时需要传入的参数,web切图报价可用于在后台任务中使用. //2. 后台任务执行时符合w3c标准,如果需要在界面上显示当前的进度,html切图制作则使用这个. //3. 当任务执行完毕后网页外包接活,如果需要对结果进行返回,wap前端外包则使用这个. private Context mContext = null; private ProgressDialog mDialog = null; private int mCount = 0; public TestAsyncTask(Context context) { mContext = context; } //在后台任务开始执行之间调用web前端制作,用于进行一些界面上的初始化操作 protected void onPreExecute() { super.onPreExecute(); mDialog = new ProgressDialog(mContext); mDialog.setMax(100); mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mDialog.show(); } //这个方法中的所有代码都会在子线程中运行,web前端制作我们应该在这里去处理所有的耗时任务 protected Boolean doInBackground(Void... params) { while (mCount < 100) { publishProgress(mCount); mCount += 20; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } return true; } //当在后台任务中调用了publishProgress(Progress...)方法后承接网页制作,这个方法就很快会被调用 protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); mDialog.setProgress(values[0]); } //当后台任务执行完毕并通过return语句进行返回时,div前端切图这个方法就很快会被调用 protected void onPostExecute(Boolean aBoolean) { super.onPostExecute(aBoolean); if (aBoolean && mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } } } } 可以看见Android帮我们封装好的AsyncTask还是很方便使用的web切图报价,咱们不做过多说明.接下来直接分析源码.

看下代码,web切图报价如下:

private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, result)); message.sendToTarget(); return result; } 先看下这个getHandler拿到的是哪个Handler吧网页外包接活, "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } } 看见没有web前端制作,也就是说在在UI线程中的Handler(不清楚的请阅读《Android异步消息处理机制详解及源码分析》文章).所以上面的方法其实就是将子线程的数据发送到了UI来处理承接网页制作, runnerOffset, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } } 看见没有?第7行的c = callable;其实就是AsyncTask构造函数中实例化FutureTask对象时传入的参数mWorker.12行看见result = c.call();没有?其实就是调运WorkerRunnable类的call方法符合w3c标准,所以我们回到AsyncTask构造函数的WorkerRunnable匿名内部内中可以看见如下:

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,符合w3c标准尊重分享成果】

AsyncTask在代码上比Handler要轻量级别网页外包接活,但实际上比Handler更耗资源,wap前端外包因为AsyncTask底层是一个线程池web前端制作,而Handler仅仅就是发送了一个消息队列.但是,div+css制作如果异步任务的数据特别庞大承接网页制作,AsyncTask线程池比Handler节省开销,承接网页制作因为Handler需要不停的new Thread执行.

public abstract class AsyncTask<Params, Result> { ...... private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, MAXIMUM_POOL_SIZE, TimeUnit.SECONDS, sThreadFactory); ...... } 看见没有承接网页制作,实质就是在一个线程池中执行,div前端切图这个THREAD_POOL_EXECUTOR线程池是一个常量web切图报价,也就是说整个App中不论有多少AsyncTask都只有这一个线程池.也就是说上面SerialExecutor类中execute()方法的所有逻辑就是在子线程中执行,web切图报价注意SerialExecutor的execute方法有一个Runnable参数符合w3c标准,这个参数就是mFuture对象,符合w3c标准所以我们看下FutureTask类的run()方法网页外包接活, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } 额,web前端制作没意思了.这不就是我们上面例子中的在子线程的doInBackground耗时操作中调运通知回调onProgressUpdate的方法么.

回过头继续往下看承接网页制作,所以execute就是SerialExecutor静态内部类的方法喽web切图报价,在执行execute方法时还传入了AsyncTask构造函数中实例化的第二个成员变量mFuture.我们来看下SerialExecutor静态内部类的代码,网站div+css如下:

public final AsyncTask<Params, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } 可以看见,wap前端外包execute调运了executeOnExecutor方法web前端制作,executeOnExecutor方法除过传入了params形参以外,div+css制作还传入了一个static的SerialExecutor对象(SerialExecutor实现了Executor接口).继续看下executeOnExecutor源码承接网页制作,如下:

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,承接网页制作尊重分享成果】

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处web切图报价,尊重分享成果】

4 为当年低版本AsyncTask的臭名正身 接触Android比较久的可能都知道,web切图报价在Android 3.0之前是并没有SerialExecutor这个类的(上面有分析).那些版本的代码是直接创建了指定大小的线程池常量来执行task的.其中MAXIMUM_POOL_SIZE = 128;,所以那时候如果我们应用中一个界面需要同时创建的AsyncTask线程大于128(批量获取数据,html切图制作譬如照片浏览瀑布流一次加载)程序直接就挂了.所以当时的AsyncTask因为这个原因臭名昭著.

当使用线程和Handler组合实现异步处理时网页外包接活,当每次执行耗时操作都创建一条新线程进行处理,wap前端外包性能开销会比较大.为了提高性能我们使用AsyncTask实现异步处理(其实也是线程和handler组合实现),因为其内部使用了java提供的线程池技术,web前端制作有效的降低了线程创建数量及限定了同时运行的线程数承接网页制作,还有一些针对性的对池的优化操作.所以说AsyncTask是Android为我们提供的方便编写异步任务的工具类.

3-2 AsyncTask的execute方法源码分析 正如上面实例一样,div前端切图得到AsyncTask实例化对象之后就执行了execute方法web切图报价,所以看下execute方法的源码,web切图报价如下:

$(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });

点击次数:14167
作者:
web前端行业资讯
Web new NewsList
谷歌安全博客披露“英特尔内核漏洞”更多细节 ,,2018年01月04日Postgres10开发者新特性 ,,2017年12月28日阿里巴巴、狗尾草、苏大联合论文:基于对抗学习的众包标注用于中文命名实体识别 ,,2017年12月28日柯洁的2017:20岁,与AI斗与人类斗,其乐无穷 ,,2017年12月28日如果机器人拥有痛觉,这个世界会有哪些不一样? ,,2017年12月28日苹果经典电脑Lisa源代码修复完成将于2018年开源 ,,2017年12月28日腾讯浏览指数发布年终榜单2017年人们都关注哪些AI话题? ,,2017年12月28日除了发现开普勒90,NASA还靠AI做了什么? ,,2017年12月28日柯洁宣布:明年4月,将再次与围棋AI交锋 ,,2017年12月28日百度无人车美国首秀CES将发布Apollo2.0 ,,2017年12月28日这四种技术发展趋势将在2018年改变世界 ,,2017年12月28日2017:谷歌DeepMind团队的年度回顾 ,,2017年12月28日封杀这个公式,AI智商将为零 ,,2017年12月28日微软AI高管:要让所有人、所有机构都用上人工智能 ,,2017年12月28日为什么Linux桌面年一直未到来 ,,2017年12月28日AppleLisa操作系统将开源 ,,2017年12月28日2018年9大技术趋势预测 ,,2017年12月28日谷歌研究院发布NIMA:能评价图像有多美,还能让图像变得更美 ,,2017年12月28日苹果为2019年iPhone开发大容量电池新技术 ,,2017年12月28日谷歌发布Tacotron2:能更简单地训练AI学习演讲 ,,2017年12月21日TensorFlow漏洞爆发背后:关于AI安全我们的傻与天真 ,,2017年12月21日Android端Edge浏览器新版发布:常规性能优化和BUG修复 ,,2017年12月21日三星开发出全球最小的DRAM芯片技术领先优势扩大 ,,2017年12月21日腾讯绝艺AI下一步将学习AlphaGozero自对弈训练 ,,2017年12月21日Facebook社交VR应用Spaces扩大覆盖面:入驻HTCVive ,,2017年12月21日设计图曝光:三星双屏折叠手机原来是这样的 ,,2017年12月21日微信支付和支付宝已成为世界移动支付的"老师" ,,2017年12月21日新专利表明FaceID未来有望装备在iPad、MacBook和iMac等设备 ,,2017年12月21日首批九个建议加入EE4J的项目 ,,2017年12月21日这就是SurfacePhone?微软可折叠手机概念图曝光 ,,2017年12月21日最短路径(一)—Floyd-Warshall(只有五行的算法) 【数据库】2015年02月02日VS2012不能创建数据库连接出现或者连接数据库时提示:未能加载文件或程序集“Microsoft.SqlServer.Management.Sdk.Sfc,Version=10.0.0.0,C 【编程语言】2014年11月24日H3Cconfigvlanaccessandtrunklinks【移动开发】2015年09月15日hdu1789DoingHomeworkagain贪心 【编程语言】2015年07月10日Java类库与用户互动 【移动开发】2015年03月02日如何用XFire在Web应用中搭建WebService 【综合】2015年07月24日Causedby:org.hibernate.DuplicateMappingException:Duplicateclassentitymapping 【综合】2015年03月10日众筹鼻祖Kickstarter成立八年众筹额超30亿美元 ,,2017年05月04日CentOS修改SSH端口【系统运维】2015年06月24日安胜安全操作系统的安全机制【涉及自主访问控制、强制访问控制、多级安全等实验】 【架构设计】2015年04月27日SSH2整合--配置+详解【数据库】2015年09月01日HDOJ题目3964FindTheSimpleCircle(DFS)【编程语言】2015年03月11日如何正确启动网站数据分析工作2014年01月28日图像编解码相关知识1【移动开发】2015年03月09日Photoshop更改图片颜色【编程语言】2015年06月30日用ASP代码实现对IP的访问限制的代码2014年01月29日php多用户读写文件冲突的解决办法2014年01月29日OpenGL:纹理基础总结 【编程语言】2014年12月16日Java面试题集(1-50)【架构设计】2015年04月24日C#中显示引用类型变量的内存地址(以字符串为例) 【编程语言】2014年12月01日拉里·佩奇拯救我的20句话,相信也会警醒你【综合】2015年08月25日BZOJ-3110-K大数查询-ZJOI2013-整体二分 【编程语言】2015年03月26日HDU1875畅通工程再续【编程语言】2015年08月14日NOJ网络赛B题pdf的旅游【移动开发】2015年04月01日HDU5325CRAZYBOBO排序【编程语言】2015年07月29日ASP编程入门进阶(二):认识表单2014年01月29日WindowsPhone8谍照疑曝光 ,,2016年06月23日汉诺塔-递归实现【编程语言】2015年07月07日(hdustep3.2.3)SuperJumping!Jumping!Jumping!(DP:求最长上升子序列的最大和)【移动开发】2015年02月11日基于xtion树莓派B+和树莓派2的OpenNI移植2015年03月24日
我们保证
We guarantee
> psd效果文件手工切图,保证图片效果最好体积最小利于传输
> 100%手写的HTML(DIV+CSS)编码,绝对符合W3C标准
> 代码精简、css沉余量小、搜索引擎扫描迅速,网页打开快捷
> 应用Css Sprite能够减少HTTP请求数,提高网页性能
> 跨浏览器兼容(IE6、7、8、9,Firefox火狐,Chrome谷歌)