android中异步任务AsyncTask的应用和工作原理

原创 2016年05月31日 18:55:01

android4.0之后,android不允许在UI线程(主线程)中运行其他耗时线程,如网络请求的线程,否则就会崩溃抛出NetWorkOnMainThreadException

而且将耗时线程放入主线程中执行,会大大影响客户体验,所以android为我们提供了其他的处理方法,其中一种常用的就是,异步任务AsyncTask;

AsyncTask的底层其实是对Thread、Handler、Message的封装,智能的应用了Handler(子线程将运行结果返回到handler队列中,主线程定时扫描该队列,取出要用的值);

我们一般可以新建一个类**Task继承于AsyncTask类,通过覆写其方法实现主线程和子线程的数据交互:


1,新建一个任务继承AsyncTask需要传入三个参数,即:<Params, Progress, Result>

2,启动异步方法:new **Task().excute(?);?处用来向**Task()方法传值,即上面的Params(一般用map<>,或String);注意:每new一个对象只能进行一次调用excute()操作
3,常用的覆写方法有:

onpreExcute():此方法在开启异步方法后,第一个执行,属于对主线程的操作;应用:比如让某个控件隐藏等操作放进这个方法里;

onInBackground():此方法执行后,异步方法会自动开启一个线程(为什么不说new一个线程,这涉及到其底层的工作原理,后面会有阐述),执行该方法内部的逻辑,这个方法属于子线程的操作,要跟其他方法有所区分;

此方法会接收第一个参数Params,进行处理,并返回第三个参数Result,并可以在过程中进行第二个参数progress的赋值,通过publishProgress()方法将数值传递给下一个方法onProgressUpdate();

onProgressUpdate();此方法通过setProgress()处理从上面方法接收过来的数据,对UI线程的进度条控件进行管理;

onPostEcute():此方法可以接受onInBackground返回的Result,并对UI线程的某个控件进行管理;

4,异步方法的工作原理:

在异步方法工作时,会用到三个概念:任务队列缓冲池、线程池、线程队列

首先,当某个Task类继承了AysncTask并开启了excute()方法后,该任务就会进入任务队列缓冲池中进行排队,等待CPU的调度

其次,当该Task类的对象执行了onInBackgrond()方法后,系统会在线程池中找空闲线程,如果有,将给任务交给这个空闲线程处理,如果没有,会new一个线程来处理这个任务;

再次,接到任务的线程会进入到线程队列中进行排队,等待CPU的调用,和其他任务线程快速切换执行;

(扩展:为什么”其次“中会存在空闲线程?因为在系统的实际运行过程中,线程的开启和销毁会消耗大量的CPU资源,系统为了避免这种情况导致的系统卡顿,会建一个线程池,用来维护线程的持续运转,即当一个线程结束时,不会让它销毁,而是让其空转,等待接收其他任务,直到线程池销毁,线程才会销毁,这是android后台对线程的优化处理;另外,异步任务的线程池存放线程数量是有上限的(这也决定了异步任务只能处理稳定的,轻量级的多线程任务),超过其线程数量,任务将不会得到执行)

=================================

android3.0之前,异步任务是并发执行的,即几个任务同时切换执行,3.0之后,异步任务改成了顺序执行,即任务队列中的任务要一个个执行(并非按顺序),一个执行不完,不能执行另一个,即,顺序执行,他是默认的执行方式-execue()方法,其默认执行的方法是:executeOnExecutor(AsyncTask.SERIAL_EXECUTOR),如果要并发执行,需要执行AsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)且为了防止系统的任务繁重,只在线程池中维护了5个线程,也就是,每次最多跑5个任务(类似于迅雷下载)。如果需要并发更多的任务,需要自定义线程池了。所以异步任务只适合处理一些轻量级的并随时修改UI的异步线程,如果遇到繁重的任务,最好自己新建一个Thread并用handler和looper机制处理。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

源码解析Android中AsyncTask的工作原理

在之前的博客《Android中AsyncTask使用详解》中我们提到AsyncTask是对Thread和Handler的组合包装,本文将通过解析的方式让大家了解AsyncTask的工作原理。Async...

Android 事件总线OTTO用法快速入门

一、Otto介绍 OTTO是Square推出的库,地址:https://github.com/square/otto 先来看看otto的官方介绍 An enhanced Guava-based eve...

从头认识java-特辑-foreach在java里面两种实现原理总结

这一章节我们来讨论一下foreach在java里面两种实现原理总结。1.数组在数组里面,是固有的foreach实现,直接循环数组(1)代码清单package com.ray.test; public...

《Linux命令行与shell脚本编程大全》 第一、二章 学习笔记

第一章:初识Linux shell Linux内核负责以下4个主要功能: 1.系统内存管理 2.软件程序管理 3.硬件设备管理 4.文件系统管理 1.系统内存管理 内核不仅管理服务器上的可用物理内...
  • su1216
  • su1216
  • 2012-11-22 21:50
  • 10620

Android解耦库EventBus的使用和源码分析

讲解了EventBus开源库的使用,详细描述了EventBus中四种订阅函数的区别,最后对EventBus主要源码进行分析,讲解了EventBus的实现机制,从而让读者不仅会使用EventBus,并从...

GLide加载图片你这样玩过吗——基于Glide4.0完美封装

一个基于GLide加载图片的封装开源框架。可以监听加载图片时的进度 ,可以设置图片的圆角、边框。可加载成圆形。来自孙福生一个开源框架。项目地址为:https://github.com/sfsheng0...

快速排序最好,最坏,平均复杂度分析

转自http://book.51cto.com/art/201108/287089.htm 很好的一篇详细数学分析快排复杂度的文章~ 我们来分析一下快速排序法的性能。快速排序的时间性能取决于...

serialable 和 parcelable详解

1. Serialable接口      对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。当然这其实远远不够,...

Android照片墙应用实现,再多的图片也不怕崩溃

照片墙这种功能现在应该算是挺常见了,在很多应用中你都可以经常看到照片墙的身影。它的设计思路其实也非常简单,用一个GridView控件当作“墙”,然后随着GridView的滚动将一张张照片贴在“墙”上,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)