现在的位置: 首页 > 综合 > 正文

Android学习笔记之编译系统(六)framework的编译过程

2013年01月13日 ⁄ 综合 ⁄ 共 6618字 ⁄ 字号 评论关闭

转载请注明出处:http://blog.csdn.net/droyon/article/details/8655031

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文件。

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。

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对应的源码文件规则定义如下:

ext_dirs := \
        ../../external/nist-sip/java \
        ../../external/apache-http/src \
        ../../external/tagsoup/src \
        ../../external/libphonenumber/java/src

ext_src_files := $(call all-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中,源文件定义如下:

OCAL_SRC_FILES := $(call find-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))

这里用到了变量

FRAMEWORKS_BASE_SUBDIRS

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指定私有资源的输出路径。

 <private-symbols package="com.android.internal" />

public指定了编译到androd.jar中的资源

<public type="attr" name="theme" id="0x01010000" />
  <public type="attr" name="label" id="0x01010001" />
  <public type="attr" name="icon" id="0x01010002" />
  <public type="attr" name="name" id="0x01010003" />
  <public type="attr" name="manageSpaceActivity" id="0x01010004" />
  <public type="attr" name="allowClearUserData" id="0x01010005" />
  <public type="attr" name="permission" id="0x01010006" />
  <public type="attr" name="readPermission" id="0x01010007" />
  <public type="attr" name="writePermission" id="0x01010008" />
  <public type="attr" name="protectionLevel" id="0x01010009" />
  <public type="attr" name="permissionGroup" id="0x0101000a" />
  <public type="attr" name="sharedUserId" id="0x0101000b" />
  <public type="attr" name="hasCode" id="0x0101000c" />
  <public type="attr" name="persistent" id="0x0101000d" />
  <public type="attr" name="enabled" id="0x0101000e" />
  <public type="attr" name="debuggable" id="0x0101000f" />
  <public type="attr" name="exported" id="0x01010010" />
  <public type="attr" name="process" id="0x01010011" />
  <public type="attr" name="taskAffinity" id="0x01010012" />
  <public type="attr" name="multiprocess" id="0x01010013" />
  <public type="attr" name="finishOnTaskLaunch" id="0x01010014" />

这样就会产生两个R.java文件。

2、编译aidl文件到android.jar中。

我们在开始说了,如果想把aidl文件编译到framework.jar中就需要在LOCAL_SRC_FILES中包含aidl文件。如果要把aidl文件编译到公开库android.jar中,需要给aidl_files赋值。

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文件的添加规则。

抱歉!评论已关闭.