最近发现了一个奇怪的问题,一处很久前写的代码,通过AsyncTask的doInBackground进行后台处理,突然间不管用了,就是说doInBackground没有被执行。同事查询SVN,发现相关代码没有过任何更改,经过很久的检查,发现只有在Manifest中有一处很小的改动,就是添加了targetSDKVersion。将这个属性去掉,就没有问题了。
通过对源码和google group以及stackoverflow的各种查找和测试,发现google挖了两个坑,不幸的是,我们跳了。
第一个坑:AsyncTask在Android各个版本中可以算是频繁修改了,比较各版本代码发现,修改过多次,而且这种修改会导致很大的差别。最坑的修改是在Android 4.0开始的,AsyncTask的中execute方法的实现在4.0以前是采用Thread pool executor,各个版本对线程池中的可并行线程数限制不同,但毕竟多个Task是多线程并行。而在4.0开始,改为用serial executor,就是说同一时间只能有一个线程运行,其他线程必须等待该线程完成之后才能开始执行,因此就变成了串行的worker thread。
第二个坑:targetSDKVersion,这个属性其实很多开发者都没有注意到,Google在官方文档中的解释又十分复杂,导致它出了问题就很难定位。总的来说,这个属性是Google为了进行兼容性检查来设置的,有一些API,例如AsyncTask这种,会根据它的设置来选择执行方式。如果targetSDKVersion设置成了4.0,那么系统就认为你的应用在4.0版本上有了足够的测试,不会有问题,那么会选择4.0的各种新特性,就是说用serial executor来实现AsyncTask。如果不加入targetSDKVersion,默认这个值会等于minSDKVersion,这时候系统认为你没有在4.0版本上测试,为了防止出问题,在4.0手机上会采用Thread pool executor来实现AsyncTask。因此就导致了我们之前的问题。
Google对AsyncTask增加了一个方法,executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ....);通过这个方法可以强制系统用Thread pool executor实现。但是需要API level 11,调用也会很麻烦。还是要注意逻辑,对长时间占用背景线程的操作避免用AsyncTask,或者自己写一个AsyncTask更靠谱一些。
相关推荐
2. **版本兼容性**:从Android 3.0(API级别11)开始,`AsyncTask`的执行默认是在单线程模式下,即所有任务都会顺序执行。如果需要多线程执行,需在应用清单文件中声明`android:targetSdkVersion`为11或更高。 3. **...
7. **Android SDK版本兼容性**:项目中可能涉及不同Android版本的兼容性问题,例如使用`minSdkVersion`、`targetSdkVersion`和`compileSdkVersion`来确保应用能在指定版本的Android设备上运行。 8. **性能优化**:...
- 遵循Android的版本适配策略,如使用`TargetSdkVersion`和`MinSdkVersion`。 9. **测试与调试**: - 使用Android Studio内置的模拟器或连接真实设备进行测试。 - 利用单元测试、集成测试以及UI自动化测试确保...
12. **版本兼容性**:由于Android设备型号众多,API级别各异,开发者需要关注API兼容性问题,通常通过`minSdkVersion`、`targetSdkVersion`和`maxSdkVersion`来控制。 在"Android_API中文合集.pdf"这份文档中,你...
- 使用`TargetSdkVersion`和`MinSdkVersion`指定支持的Android版本范围。 10. **测试与调试** - 全面测试不同设备、分辨率和Android版本上的表现。 - 使用Android Studio的模拟器和真机调试工具进行调试。 通过...
设置`targetSdkVersion`可以帮助确保应用遵循新版本的API最佳实践,而`minSdkVersion`定义了应用能运行的最低Android版本。 在注册和登录过程中,通常会涉及到以下几个关键组件: 1. **用户界面**:包含输入框...
4. **编译设置**:检查项目的build.gradle文件,确认编译目标(minSdkVersion、targetSdkVersion)与你的设备或模拟器相匹配。如有需要,根据项目需求调整编译配置。 5. **编译与运行**:在一切准备就绪后,点击...
可以使用`Build.VERSION.SDK_INT`检查当前系统版本,并根据需要使用`@TargetApi`和`@SuppressLint`注解。 综上所述,实现"获得Android系统中所有已安装的应用并联网检测自动升级更新"的功能,需要掌握Android系统的...
使用`Build.VERSION.SDK_INT`检查版本,并使用条件编译(如`@TargetApi`和`@SuppressLint`注解)来处理特定API级别的特性。 以上就是关于“android客户端服务器段”开发的一些主要知识点,涵盖了从网络通信到数据...
9. **Android SDK版本适配**:虽然源码基于API 9,但也可以学习如何针对不同版本的Android进行兼容性开发,比如使用`@TargetApi`和`@SuppressLint`注解,以及`Build.VERSION.SDK_INT`来判断版本。 10. **代码注释**...
- 版本兼容性:源码应考虑不同Android版本的兼容性,可能使用`Build.VERSION.SDK_INT`检查API级别,并使用条件编译指令(`@TargetApi`, `@SuppressLint`)来处理差异。 8. **性能优化**: - `AsyncTask`或`Thread`...
确保在Android Studio中,项目的build.gradle文件中的`targetSdkVersion`和`minSdkVersion`设置得当,以支持动态权限请求。同时,使用最新的Android SDK和构建工具,以保持代码的兼容性和最佳实践。 7. **源码软件...
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="8"/> ``` - **添加 supports-screens 节点**:确保应用能在多种分辨率和屏幕尺寸上正常运行。 ```xml ``` - **引入特性节点**:指定应用所需...
10. **版本兼容性**:Android系统版本众多,为了保证兼容性,可能使用了`Build.VERSION.SDK_INT`检查API级别,并使用条件编译(`@TargetApi`, `@SuppressLint`)来处理不同版本间的差异。 总结来说,Android ...
可能需要使用条件编译指令(如`@TargetApi`、`Build.VERSION.SDK_INT`等)来确保代码在各个版本上的正确执行。 总的来说,这个压缩包中的实例代码涵盖了Android中关于广播接收器、电话状态监听、悬浮窗权限、自定义...
10. **版本适配**:考虑到Android设备的多样性和版本差异,源码可能包含了针对不同API级别的兼容性处理,比如使用`@TargetApi`和`@SuppressLint`注解,以及`Build.VERSION.SDK_INT`的检查。 通过深入研究这个源码...
10. **版本适配**:Android平台碎片化严重,开发者需要考虑不同版本间的兼容性问题。通过使用Support Library(现在称为AndroidX库)和Target SDK Version,可以确保应用在较旧设备上的正常运行。 "android...