一.问题背景
设备(17),app一开始开了一个AsyncTask阻塞式接收消息(也就是一直执行不完),那么问题来了
关于AsyncTask版本的问题,可以看看AsyncTask介绍
targetSdkVersion设置 大于12 那么就是串行执行,如果新开了了一个AsyncTask就不会执行,因为前面那个AsyncTask阻塞没执行玩
targetSdkVersion设置 小于12 那么就是并行执行,任务之间互不干扰
二.问题原因
我们先看这个targetSdkVersion是啥意思
下面是谷歌的官方文档的介绍
android:targetSdkVersion
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写阻塞方法