framework的编译是对framework目录下所有的子目录的编译。framework在编译后会生成几个重要的jar包。他们是framework.jar、core.jar、ext.jar、framework-res.jar。framework.jar包是framework层Java源文件编译的。core.jar是dalvik虚拟机运行时所需要的java运行库文件。ext.jar包含了一些可扩展的类库文件。framework-res.jar包含了framework中所使用的各种资源文件。
framwork层的编译过程可分为一下几步:
1、编译aidl文件。使用LOCAL_SRC_FILES变量包含需要编译的aidl文件。
[java] view plain copy
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
core/java/android/accessibilityservice/IEventListener.aidl \
core/java/android/accounts/IAccountManager.aidl \
core/java/android/accounts/IAccountManagerResponse.aidl \
core/java/android/accounts/IAccountAuthenticator.aidl \
core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
core/java/android/app/IActivityController.aidl \
core/java/android/app/IActivityPendingResult.aidl \
core/java/android/app/IActivityWatcher.aidl \
core/java/android/app/IAlarmManager.aidl \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
core/java/android/app/INotificationManager.aidl \
core/java/android/app/IProcessObserver.aidl \
core/java/android/app/ISearchManager.aidl \
core/java/android/app/ISearchManagerCallback.aidl \
core/java/android/app/IServiceConnection.aidl \
core/java/android/app/IThumbnailReceiver.aidl \
2、生成core.jar。
[java] view plain copy
LOCAL_JAVA_LIBRARIES := bouncycastle core core-junit ext
这里的core是Dalivik虚拟机运行时所需要的java库,并不是framework/base/core目录下的文件。core的目标是在根目录的libcore目录下定义的。
首先编译dx工具和dx.jar,编译core后生成core.jar,这两个工具用于将core.jar转换为dex文件。
将core目标对应的jar文件转换为dex文件。
将dex打包到core.jar中。
3、生成bouncycastle.jar。
4、生成core-junit.jar。
5、编译生成ext.jar,ext对应的源码文件规则定义如下:
[java] view plain copy
ext_dirs := \
../../external/nist-sip/java \
../../external/apache-http/src \
../../external/tagsoup/src \
../../external/libphonenumber/java/src ext_src_files := (callall−java−files−under,(ext_dirs))
ext_res_dirs := \
../../external/libphonenumber/java/src
6、编译生成framework-res.jar,所需的R.java文件。framework-res.jar是framework下的资源文件编译而成,framework层代码由于文件过多,framwork在编译时不是编译成一个jar,而是分成了两部分,一部分是资源文件,也就是framework-res.jar,另一部分就是dex文件,他是framework源码输出。
7、编译生成framework.jar。framework层下源代码编译到framework.jar中,源文件定义如下:
[java] view plain copy
OCAL_SRC_FILES := (callfind−other−java−files,(FRAMEWORKS_BASE_SUBDIRS))
EventLogTags files.
LOCAL_SRC_FILES += \
core/java/android/content/EventLogTags.logtags \
core/java/android/speech/tts/EventLogTags.logtags \
core/java/android/webkit/EventLogTags.logtags \
telephony/java/com/android/internal/telephony/EventLogTags.logtags \
The following filters out code we are temporarily not including at all.
TODO: Move AWT and beans (and associated harmony code) back into libcore.
TODO: Maybe remove javax.microedition entirely?
TODO: Move SyncML (org.mobilecontrol.*) into its own library.
LOCAL_SRC_FILES := (filter−out org/mobilecontrol/,(LOCAL_SRC_FILES))
这里用到了变量
[java] view plain copy
FRAMEWORKS_BASE_SUBDIRS
[java] view plain copy
FRAMEWORKS_BASE_SUBDIRS := \
$(addsuffix /java, \
core \
graphics \
location \
media \
media/mca/effect \
media/mca/filterfw \
media/mca/filterpacks \
drm \
opengl \
sax \
telephony \
wifi \
keystore \
icu4j \
voip \
fmradio \
)
我们在前面的文章说过,这个变量定义了编译到framework.jar中的文件的目录。这个变量在pathmap.mk中定义。如果我们要添加java文件,如果这个java文件的路径在这些目录下,那么直接编译就ok,如果不再这些目录下,那么还需修改LOCAL_SRC_FILES或者修改FRAMEWORKS_BASE_SUBDIRS,使其包含新添加的文件。
8、编译生成framework-res.jar。
进行签名,以及边界压缩对齐等操作。
9、Android.jar。sdk的一部分,第三方应用程序可以调用的资源。
在framework层代码编译过程中,我们还会生成一个android.jar,这个文件是framework.jar的子集,framework层文件包括aidl文件,res目录下的资源,java源文件三部分。而这些文件是分两类的,一类是公有资源,另一类是私有资源。android版本到目前为止经历了1.5、2.2、2.3、4.0、4.1、4.2,最新的代码为4.2,android为了保证应用程序向后兼容,所以定义了公有资源,即最新的公有资源会包含较旧版本公有资源的内容。私有资源是在每个版本中自己使用的一些资源,这些资源随着版本可能会存在差异。
公有资源是要编译到android.jar中的,android.jar要打包进sdk中,这样借助sdk开发的应用程序可以引用framework资源。
1、如何将规定资源编译到android.jar中?
总结:资源文件是使用aapt工具进行编译的,每个资源都有一个id,这个id一般是aapt自动生成的,不过应用程序也可以在事前给资源指定id,这就要通过public.string文件来指定。
关于资源的id的编码:0x07 01 0001
资源开头有三种:0x07、0x01、0x02。07代表普通应用类的资源,在package/app下的应用都是这种。01:代表framework层的资源。02代表普通的非应用资源。
接下来两位代表资源类型:01代表attr资源,02代表drawable资源,03代表layout资源,04代表string资源。
在接下来后四位代表资源id编号。
framework/base/core/res/res/values/下有个public.string文件,在这个文件中,定义了public开头的是可以编译到android.jar中的资源。
通过private-symbols指定私有资源的输出路径。
[java] view plain copy
public指定了编译到androd.jar中的资源
[java] view plain copy
这样就会产生两个R.java文件。
2、编译aidl文件到android.jar中。
我们在开始说了,如果想把aidl文件编译到framework.jar中就需要在LOCAL_SRC_FILES中包含aidl文件。如果要把aidl文件编译到公开库android.jar中,需要给aidl_files赋值。
[java] view plain copy
aidl_files := \
frameworks/base/core/java/android/accounts/IAccountManager.aidl \
frameworks/base/core/java/android/accounts/IAccountManagerResponse.aidl \
frameworks/base/core/java/android/accounts/IAccountAuthenticator.aidl \
frameworks/base/core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
frameworks/base/core/java/android/app/Notification.aidl \
frameworks/base/core/java/android/app/NotificationGroup.aidl \
frameworks/base/core/java/android/app/Profile.aidl \
frameworks/base/core/java/android/app/PendingIntent.aidl \
frameworks/base/core/java/android/bluetooth/BluetoothDevice.aidl \
frameworks/base/core/java/android/bluetooth/BluetoothHealthAppConfiguration.aidl \
frameworks/base/core/java/android/content/ComponentName.aidl \
frameworks/base/core/java/android/content/Intent.aidl \
frameworks/base/core/java/android/content/IntentSender.aidl \
frameworks/base/core/java/android/content/PeriodicSync.aidl \
frameworks/base/core/java/android/content/SyncStats.aidl \
frameworks/base/core/java/android/content/res/Configuration.aidl \
frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
frameworks/base/core/java/android/net/Uri.aidl \
3、如何定义编译到android.jar中的java文件。
总结:是通过javadoc工具获取的。
framework层下的所有java代码,所有的非@hide修饰的类、方法、变量都会到处到public_api.xml中,产生public_api.xml文件后,编译系统会复制它产生current.xml。
这就是android.jar中java文件的添加规则。