Android系统开发--6.Android不编译某个内置模块

android 系统内置了很多应用,比如说通信录,日历,计算器,相机等, 对于 TV 来说,这些应用是没有什么用的,只是占用系统空间而已。为了节剩一下系统空间,我们在编译系统时要把这些模块给去掉。以下介绍两种方法来达到我们的目的。

1. 直接从 PRODUCT_PACKAGES 中删除

比如说我们要删除通信录 Contacts 这个应用,我们可以查找一下这个应用是在哪里加入到 PRODUCT_PACKAGES 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
qiushao@qiushao-PC:~/source/android-8.1$ mgrep Contacts
./build/make/target/product/core_tiny.mk:22: ContactsProvider \
./build/make/target/product/core_base.mk:24: ContactsProvider \
./build/make/target/product/core.mk:33: Contacts \
./device/google/atv/products/atv_base.mk:32: ContactsProvider \
./platform_testing/build/tasks/tests/instrumentation_test_list.mk:35: ContactsProviderTests \
./platform_testing/build/tasks/tests/instrumentation_test_list.mk:36: ContactsProviderTests2 \
./packages/services/Car/car_product/build/car_base.mk:23: ContactsProvider \
./packages/services/Telephony/Android.mk:3:# Build the Phone app which includes the emergency dialer. See Contacts
./packages/apps/Contacts/CleanSpec.mk:50:$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Contacts_intermediates)
./packages/apps/Contacts/tests/Android.mk:13:LOCAL_PACKAGE_NAME := ContactsTests
./packages/apps/Contacts/tests/Android.mk:15:LOCAL_INSTRUMENTATION_FOR := Contacts
./packages/apps/Contacts/Android.mk:53:LOCAL_PACKAGE_NAME := Contacts
./packages/providers/ContactsProvider/tests2/Android.mk:23: ContactsProviderTestUtils \
./packages/providers/ContactsProvider/tests2/Android.mk:32:LOCAL_PACKAGE_NAME := ContactsProviderTests2
./packages/providers/ContactsProvider/tests2/Android.mk:35:LOCAL_INSTRUMENTATION_FOR := ContactsProvider
./packages/providers/ContactsProvider/test_common/Android.mk:29:LOCAL_MODULE := ContactsProviderTestUtils
./packages/providers/ContactsProvider/tests/Android.mk:8: ContactsProviderTestUtils \
./packages/providers/ContactsProvider/tests/Android.mk:18:LOCAL_PACKAGE_NAME := ContactsProviderTests
./packages/providers/ContactsProvider/tests/Android.mk:21:LOCAL_INSTRUMENTATION_FOR := ContactsProvider
./packages/providers/ContactsProvider/Android.mk:22:LOCAL_PACKAGE_NAME := ContactsProvider
./cts/tests/tests/contactsproviderwipe/Android.mk:35:LOCAL_PACKAGE_NAME := CtsContactsProviderWipe

看一下搜索的结果应该可以知道是 ./build/make/target/product/core.mk 这个文件里面添加了 Contacts 应用。 很多系统原生的应用也是在这里面添加的。我们可以直接在这里面删除即可。

2. 通过 LOCAL_OVERRIDES_PACKAGES 删除

虽然通过前面的方法基本上可以满足我们的需求了,但是需要修改系统原生的配置,不好维护。后来发现一种更好维护的方法。在 device/qiushao 目录下添加 Android.mk 里面添加一个模块 remove_unused_module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
include $(CLEAR_VARS)
LOCAL_MODULE := remove_unused_module
LOCAL_MODULE_TAGS := optional

LOCAL_MODULE_CLASS := FAKE
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

LOCAL_OVERRIDES_PACKAGES += \
Contacts \
Email

include $(BUILD_SYSTEM)/base_rules.mk

$(LOCAL_BUILT_MODULE):
$(hide) echo "Fake: $@"
$(hide) mkdir -p $(dir $@)
$(hide) touch $@

PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))

这里需要注意的是 $(hide) echo "Fake: $@" 前面是 TAB,不是空格, Makefile 语法的要求。

然后在 device/qiushao/generic_pure/generic_pure.mk 里面添加

1
PRODUCT_PACKAGES += remove_unused_module

将要去掉的模块添加到 LOCAL_OVERRIDES_PACKAGES 就可以了,统一管理,很方便。
下面来验证一下。把 out/target/product/generic_pure/system 目录删除,然后重新编译,运行,发现Contacts,Email这两个应用的确是不见了。

3. LOCAL_OVERRIDES_PACKAGES 原理

LOCAL_MODULE_CLASS := FAKE 指定编译输出的目录为 $(PRODUCT_OUT)/fake_packages, 也就是不会打包到系统里面。
LOCAL_OVERRIDES_PACKAGES 定义本模块要覆盖的模块,也就是本模块被编译的话,被覆盖的模块就不会被编译了。在 main.mk 里面有对 OVERRIDES_PACKAGES 进行处理

1
2
3
4
5
6
7
8
9
# Some packages may override others using LOCAL_OVERRIDES_PACKAGES.
# Filter out (do not install) any overridden packages.
overridden_packages := $(call get-package-overrides,$(modules_to_install))
ifdef overridden_packages
# old_modules_to_install := $(modules_to_install)
modules_to_install := \
$(filter-out $(foreach p,$(overridden_packages),$(p) %/$(p).apk %/$(p).odex %/$(p).vdex), \
$(modules_to_install))
endif

modules_to_install 是所有要编译的模块,
overridden_packages 就是指要覆盖的模块了,一般来说是通过在各模块的 Android.mk 里面通过 LOCAL_OVERRIDES_PACKAGES 指定的。
filter-out 就是过滤掉。
这段代码的意思就是将 overridden_packages 从 modules_to_install 中删除掉。