对于线程池和AsyncTask的理解

关于线程

android 中每一个APP都运行在一个独立的进程中。每一个APP进程都有一个主线程,也被称为UI线程.

android系统不允许应用在非主线程中进行UI更新操作,所有的UI更新操作都必须在主线程中进行。

因此,我们不能在主线程中做过于耗时的任务。因为这样会导致UI的更新被堵塞,出现卡顿,黑屏,或者ANR。

关于网络访问

android系统在3.0开始如果在主线程执行网络操作,会抛出NetworkOnMainThread不能访问网络异常。
因为网络访问很多时候是耗时的操作,不应该在主线程中运行。

总结上述两段话:如果我们要进行网络访问的操作,正确的做法:先开启一个线程去执行网络访问任务,
然后保存返回的数据,并发送通知给主线程,让主线程去UI控件上更新我们获取到的数据。

AsyncTask值得借鉴的地方和局限性:

AsyncTask抽象了执行异步任务所要考虑的基本要素。
如线程的开启,完成任务后通过handler发送消息给主线程,在任务的执行过程中停止任务。
我们只需要在其提供的回调方法中去做相应的操作即可。

AsyncTask相比手动创建一个线程去执行任务的最大好处是它内部实现了一个线程池,
这个线程池作用于同一个应用进程中所有使用AsyncTask去执行的异步任务。

关于线程池

线程池能够统一管理所有的异步线程(任务),结合系统的资源(CPU数量)来控制任务
的开始,停止,任务并发的数量等。

举例说明:类似淘宝或者天猫这类的大型应用,首页可能会调用10多个网络访问相关的api。
这在网络环境较好的情况下(wifi/4g)不容易出现什么问题,但是切换到2G网络的时候。
我们先访问APP首页,然后快速从首页跳到二级页面。这时候首页调用的api还没来得及执行完,
又要在二级页面去做其他的网络访问操作。这显然浪费了系统资源。所以我们需要有一个线程池,
来管理我们开启过的线程。在必要的时候控制线程的开始或者停止。

AsyncTask中带有的坑:

  • AsyncTask在不同版本上会有差异:
    在2.x版本中,调用excute方法,所有任务是并发执行的,并发数是CPU数量+1
    在4.x版本中,调用excute方法,所有任务是串行执行的。同时另外提供了一个 excuteOnExcutor方法
    来让任务并发执行。

  • AsyncTask不适合做耗时任务。从上一条分析可以知道,即时我们采用并发执行,并发数量也是有限制的,如果我们去做一些类似文件之类的耗时任务,当并发数达到最大值,后面的任务就会排队等待。如果是串行执行,那就更慢了,我们要等待每一个任务执行完,才能执行下一个任务,前面说过AsyncTask管理的是一个应用进程中所有使用AsyncTask创建的异步任务。如果我们用AsyncTask创建几个类似apk下载的任务。再去访问一个普通页面,如果这个页面也用AsyncTask去加载文字和图片数据的话,那么我们必须等待前面的apk下载
    完成才能看到这个页面加载的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值