AsyncTake与targetSdkVersion设置的关系产生异常(串行,并行导致的)

一.问题背景

  设备(17),app一开始开了一个AsyncTask阻塞式接收消息(也就是一直执行不完),那么问题来了

关于AsyncTask版本的问题,可以看看AsyncTask介绍

targetSdkVersion设置  大于12   那么就是串行执行,如果新开了了一个AsyncTask就不会执行,因为前面那个AsyncTask阻塞没执行玩

targetSdkVersion设置  小于12  那么就是并行执行,任务之间互不干扰

二.问题原因

我们先看这个targetSdkVersion是啥意思

下面是谷歌的官方文档的介绍

android:targetSdkVersion
An integer designating the API Level that the application targets. If not set, the default value equals that given to  minSdkVersion.

This attribute informs the system that you have tested against the target version and the system should not enable any compatibility behaviors to maintain your app's forward-compatibility with the target version. The application is still able to run on older versions (down tominSdkVersion).

As Android evolves with each new version, some behaviors and even appearances might change. However, if the API level of the platform is higher than the version declared by your app's targetSdkVersion, the system may enable compatibility behaviors to ensure that your app continues to work the way you expect. You can disable such compatibility behaviors by specifying targetSdkVersion to match the API level of the platform on which it's running. For example, setting this value to "11" or higher allows the system to apply a new default theme (Holo) to your app when running on Android 3.0 or higher and also disables screen compatibility mode when running on larger screens (because support for API level 11 implicitly supports larger screens).

There are many compatibility behaviors that the system may enable based on the value you set for this attribute. Several of these behaviors are described by the corresponding platform versions in the Build.VERSION_CODES reference.

To maintain your application along with each Android release, you should increase the value of this attribute to match the latest API level, then thoroughly test your application on the corresponding platform version.

Introduced in: API Level 4

自己翻译的:

简单的说,就是如果没有指定targetSdkVersion那么默认就等于minSdkVersion,这个属性是用来通知系统你已经在targetSdkVersion指定的版本上已经测试好了,可以完美的用,不用任何兼容性的动作。Android  更新系统,一些操作甚至样子都会改变,然而当平台的API大于指定targetSdkVersion,这时候系统可能(不是一定)会做一些兼容性的操作确保你的app能正常工作。

当然如果不想要这些兼容性操作可以通过把targetSdkVersion改成跟运行平台API一样。举个栗子把targetSdkVersion设置到11  或者更高  ,这样就能让你的app运行在平台大于等于Android3.0上应用一个新的主题(holo),而且在大屏幕上可以不用屏幕适配模式(因为API11默认支持大屏)

targetSdkVersion设置在某个值,系统为了保持正常运行会有很多兼容性操作,一些兼容性操作在Build.VERSION_CODES 有写。

为了让你app随着Android系统更新也能正常用,你必须提高targetSdkVersion到最新的API,因此你要在相应的平台测试。

这个targetSdkVersion是在API4的时候引入


最后我总结一下

1.targetSdkVersion没设置,默认等于minSdkVersion

2.targetSdkVersion 小于平台API的情况下,用的是运行平台的函数,但是有可能里面写了兼容性操作,系统可能会向下兼容(注意是可能!!!

3targetSdkVersion大于平台API的情况下,用的是运行平台的函数

4.如果是等于的话当然是完美运行



所以问题就出在第二点和第三点,当运行平台是17

当targetSdkVersion小于12

在ActivityThread中有做针对AsyncTask做兼容性处理(在Activity中可以找到ActivityThread然后可以查看源码)

    // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
        // implementation to use the pool executor.  Normally, we use the
        // serialized executor as the default. This has to happen in the
        // main thread so the main looper is set right.
        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        Message.updateCheckRecycle(data.appInfo.targetSdkVersion); 


在targetSdkVersion大于12(也就是大于android.os.Build.VERSION_CODES.HONEYCOMB_MR1)

使用运行平台的函数也就是AsynTask默认就是串行的


因此可以看出来问题的所在


三.解决问题

1.把targetSdkVersion改下,但是这是头痛剁头脚痛剁脚的方法,不建议

2.针对不同的运行平台写死AsyncTask用的串行线程池还是并行线程池

3.不要用AsyncTask写阻塞方法


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值