为了学习Android的一些内部工作原理或者解决工作中的难题,我们经常需要研究Android SDK中的源码。
研究源码有两种方式,一种是静态的阅读,一种是动态的调试。对于复杂的代码,动态调试一般会更高效实用,因为可以使用调试工具强大的功能,比如堆栈跟踪,变量查看等。在调试跟踪SDK源码时,相信大家都曾经遇到一个让人很无奈的事情,就是IDE显示的代码行号跟实现执行的代码对不上。那么是什么原因造成了这种情况呢?
简单的说就是设备的Android系统版本与编译使用的SDK版本不一致。举个例子,我们写了一个CustomView,继承SDK中的View,使用Android4.0的SDK(api 14)来编译,然后将生成的apk安装到Android2.3的手机上运行。那么问题来了,运行时使用的View到底是Android4.0的,还是Android2.3的?
答案是Android2.3的。其实在编译打包Apk时并不会把系统SDK提供的类打包进Apk,而是只打包开发者自己写的类和资源。程序在设备上运行时,当涉及到SDK中的类时,使用的都是设备所装系统提供的,而这也正是设备Android系统版本的关键,Android2.3的系统提供的便是Android2.3 SDK对应的android.jar包。而通过调试工具看到的代码是编译所使用的SDK代码。
另外介绍一下SDK版本相关的几个概念:
compileSdkVersion,决定了app所能使用的api的上限,如果编译SDK为api16的,则app不能api16之后新增的api,只能使用api16及之前的api。
minSdkVersion,决定了app所能使用的api的下限。
targetSdkVersion,如果targetSdkVersion是10但是手机系统的是11,那么系统在某些方面会做向前兼容,而不会使用最新的特性(比如大屏特性,api11才有的)。