美文网首页
AsyncTask和线程池的理解和应用

AsyncTask和线程池的理解和应用

作者: 特大碗牛肉面 | 来源:发表于2017-04-23 20:40 被阅读0次

什么是AsyncTask

AsyncTask是Android提供的轻量级的异步类, 可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行进度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。AsyncTask 有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler), 其中SerialExecutor是用来任务排队的 ,而线程池THREAD_POOL_EXECUTOR是用来真正执行任务的;  AsyncTask异步任务底层是封装了线程池和Handler 。注意兼容问题: Android 3.0以前 ,默认情况下AsyncTask是串行执行, 3.0以后才有executeOnExecutor方法;


为什么要用AsyncTask

AsyncTask的优点是简单快捷,缺点则是代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。除了使用AsyncTask外,还可以使用Handler来实现。比如我做的一些联网获取数据的操作,就是用Timer+Handler来实现的(由于使用的Socket和服务器交互,因此使用Timer来定时,在规定的时间内不响应的话视为超时。)但是,AsyncTask不适合进行提别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池;


�一个AsyncTask异步任务的执行一般包括以下几个步骤:

1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。(执行)

2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。(准备工作)

3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。(主线程中执行)

4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。(主线程中执行,当后台任务的执行进度发送改变时此方法会被调用).

5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。(异步执行后这个方法被调用)


AsyncTask的使用:

记住这几个方法就可以了 在doInBackground中写业务代码

1.我们要获取总大小totalSize,还有当前已下载大小count,由这两个数值去计算当前的下载进度: count/totalSize (注意要拿float去计算, 不然小数取整后为0)

2.计算出进度后,调用publishProgress去推送进度,调用此函数后,onProgressUpdate才会回调,并且我们将会在onProressUpdate中设置进度控件的值。

3.resultData是我们的返回值,返回resultData后,才会在OnPostExecute 中获取结果值,并吧结果值展示到界面中。

4.记得finish时释放资源.

5.异步任务的实例必须在UI线程中创建。

6.execute(Params... params)方法必须在UI线程中调用。

7.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。

8.不能在doInBackground(Params... params)中更改UI组件的信息。

9.一个任务实例只能执行一次,如果执行第二次将会抛出异常。


线程池:

Android里面,耗时的网络操作,都会开子线程,在程序里面直接开过多的线程会消耗过多的资源,使用线程池可以很好的维护程序中的线程资源;线程池是预先创建线程的一种技术。

1. 线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中,然后对这些资源进行复用。

2. 减少频繁的创建和销毁对象, 因为频繁创建和销毁线程耗资源,就会耗时间.

3.因为有的线程执行时间比创建和销毁一个线程的时间还短; 


线程池中涉及的类:

1. Executor:Java里面线程池的顶级接口。

2. ExecutorService:真正的线程池接口。

3. ScheduledExecutorService:能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。

4. ThreadPoolExecutor(重点):ExecutorService的默认实现。

5. ScheduledThreadPoolExecutor:继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。

6. Executors:可以一行代码创建一些常见的线程池

Executors介绍:

1.newSingleThreadExecutor:

创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行>所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池>保证所有任务的执行顺序按照任务的提交顺序执行。

2.newFixedThreadPool: 

创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

3.newCachedThreadPool:

创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程, 那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

4.newScheduledThreadPool:

创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。


ThreadPoolExecutor介绍:

相关参数

线程池的写法: 

ThreadPoolManager

AsyncTask和线程池结合使用:

线程池一般的使用方法:  Executors.newFixedThreadPool(...).execute(Runnable()) 并发运行;

线程池和asynctask连用 自定义一个asynctask

参考文献:

java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

《Android艺术与探究》

相关文章

网友评论

      本文标题:AsyncTask和线程池的理解和应用

      本文链接:https://www.haomeiwen.com/subject/kkzmattx.html