当前位置:   article > 正文

Android xml里面product的值来自哪里以及怎么影响编译?_ro.build.characteristics

ro.build.characteristics

   Android xml里面product的值来自哪里以及怎么影响编译?



前言

  做过Android Settings及Android原生应用开发的小伙伴们应该都知道,在其xml文件里面有根据product配置的选项,可以根据不同的product场景切换不同的资源。那么各位没有考虑过这些product的值是来自那里,以及怎么影响Settings或者其它使用product的App显示的呢?好吗,今天我将带领大伙解读一番,看看它的庐山真面!


注意:这里的Android版本是9,其它版本可能有一定差异。



一. Android xml里面product的值来自哪里

在Android Settings开发里面,我们经常能看到这样的xml字符串定义,如下所示,通过product的值来匹配合适的string资源信息,那么这个product的值从何而来呢。当然不是从天上掉下来的,下面让我们一探究竟它到底来自何方!

<string name="bluetooth_pref_summary" product="tablet" msgid="3520035819421024105">"允许您的平板电脑与附近的蓝牙设备进行通信"</string>
<string name="bluetooth_pref_summary" product="device" msgid="2205100629387332862">"允许您的设备与附近的蓝牙设备进行通信"</string>
<string name="bluetooth_pref_summary" product="default" msgid="782032074675157079">"允许您的手机与附近的蓝牙设备进行通信"</string>

 <string name="about_settings" product="tablet" msgid="593457295516533765">"关于平板电脑"</string>
 <string name="about_settings" product="default" msgid="1743378368185371685">"关于手机"</string>
 <string name="about_settings" product="device" msgid="6717640957897546887">"关于设备"</string>
 <string name="about_settings" product="emulator" msgid="221313099578564438">"关于模拟设备"</string>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.1 PRODUCT_CHARACTERISTICS赋值来源

我想绝大部分的博客会说这个值是由ro.build.characteristics这个属性确定的,其实不然这个只是最终结果的表现,而product对应的值来最开始来源于于PRODUCT_CHARACTERISTICS所对应的赋值。有过Android源码build的应该知道,一般Android的编译配置都在build和device目录下面,让我们到改目录下面搜索一番,查看一下结果:
在这里插入图片描述

1.2 ro.build.characteristics的赋值来源

可以看到TARGET_AAPT_CHARACTERISTICS依赖于PRODUCT_CHARACTERISTICS,老规矩让我们搜一搜,看看它的来源:
在这里插入图片描述
可以看到ro.build.characteristics的值最终依赖TARGET_AAPT_CHARACTERISTICS的值。

通过前面的一番折腾,大家是不是对product从哪里来有了比较清晰的认识了。虽然不是很曲折,这边还是整理一下:

  • 这个值PRODUCT_CHARACTERISTICS 是product的最初来源,譬如可以emulator,device,tablet这是不是和前面字符串中的product对应上了。
  • 然后TARGET_AAPT_CHARACTERISTICS依赖于PRODUCT_CHARACTERISTICS 的值。
  • 最后ro.build.characteristics的值依赖于TARGET_AAPT_CHARACTERISTICS,被编译进build.prop里面。

最后我们可以通过getprop查看一下这个属性的值:

xxx:/ # getprop  ro.build.characteristics
default
  • 1
  • 2

不容易啊,搞清楚product的来龙去脉。到这里我想大家应该知道怎么修改product的值了,可以根据实际的项目配置修改device下面的PRODUCT_CHARACTERISTICS值达到最终确定product的值的目的。



二. Android xml里面product的值怎么影响编译的

好了,前面的章节解决了product从哪里来,那么这个章节就来看看product的值怎么影响Android原生App里面资源的编译了。


2.1 带着疑问搜索

刚开始我以为,Android是通过ro.build.characteristics来决定选择那个字符串数据进行显示的,好吗后来才知道找个是多么的不靠谱啊,所以我搜索了framework目录,好吗一无所获。
在这里插入图片描述
不应该啊,为啥啥都没有。难道不是这个属性确定显示那个字符串吗。好吗,怪我当时短路了,不是这么回事的。


2.2 product怎么影响编译正解

在前面的章节我们搜索TARGET_AAPT_CHARACTERISTICS有如下相关信息:

xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$ grep -nr "TARGET_AAPT_CHARACTERISTICS"  device/ build/
build/make/tools/buildinfo.sh:62:echo "ro.build.characteristics=$TARGET_AAPT_CHARACTERISTICS"
build/make/core/definitions.mk:2137:  $(if $(filter --product,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --product ,$(PRIVATE_TARGET_AAPT_CHARACTERISTICS))) \
build/make/core/definitions.mk:2469:    $(if $(filter --product,$(PRIVATE_AAPT_FLAGS)),,$(addprefix --product , $(PRIVATE_TARGET_AAPT_CHARACTERISTICS))) \
build/make/core/prebuilt_internal.mk:659:$(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
build/make/core/product_config.mk:320:  TARGET_AAPT_CHARACTERISTICS := default
build/make/core/product_config.mk:322:  TARGET_AAPT_CHARACTERISTICS := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_CHARACTERISTICS))
build/make/core/static_java_library.mk:137:$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
build/make/core/static_java_library.mk:150:$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_AAPT_CHARACTERISTICS :=
build/make/core/Makefile:363:			TARGET_AAPT_CHARACTERISTICS="$(TARGET_AAPT_CHARACTERISTICS)" \
build/make/core/package_internal.mk:353:$(R_file_stamp) $(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
build/make/core/package_internal.mk:520:$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
build/make/core/soong_config.mk:85:$(call add_json_str,  AAPTCharacteristics,               $(TARGET_AAPT_CHARACTERISTICS))
xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9$ 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

让我们捋一捋,看看搜索到的信息,发现了一条有用的如下所示:

build/make/core/package_internal.mk:353:$(R_file_stamp) $(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
  • 1

这个R_file_stamp不就和APK的编译有关系吗,顺着这条路让我们看看APK Build所依赖的build/core/package.mk文件,可以看到里面有依赖于package_internal.mk,如下所示:
在这里插入图片描述

xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9/build/core$ grep -nr "package_internal.mk" package.mk 
64:include $(BUILD_SYSTEM)/package_internal.mk
77:include $(BUILD_SYSTEM)/package_internal.mk
  • 1
  • 2
  • 3

在package_internal.mk可以看到LOCAL_BUILT_MODULE_STEM被定义为package.apk

xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9/build/core$ grep -nr "package.apk"  package_internal.mk 
239:LOCAL_BUILT_MODULE_STEM := package.apk.gz
242:LOCAL_BUILT_MODULE_STEM := package.apk
xxx@Ubuntu16-Model:~/ssd/qcom_64/msm8953-9/build/core$ 
  • 1
  • 2
  • 3
  • 4

而我们知道LOCAL_BUILT_MODULE与LOCAL_BUILT_MODULE_STEM有关系。在package_internal.mk可以看到LOCAL_BUILT_MODULE依赖于R_file_stamp,具体见如下所示:

# Other modules should depend on the BUILT module if
# they want to use this module's R.java file.
$(LOCAL_BUILT_MODULE): $(R_file_stamp)

  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
而R_file_stamp会依赖resource_export_package,resource_export_package会做的动作有create-empty-package、add-assets-to-package等等:

  ifdef LOCAL_EXPORT_PACKAGE_RESOURCES
    # Put this module's resources into a PRODUCT-agnositc package that
    # other packages can use to build their own PRODUCT-agnostic R.java (etc.)
    # files.
    resource_export_package := $(intermediates.COMMON)/package-export.apk
    $(R_file_stamp): $(resource_export_package)

    # add-assets-to-package looks at PRODUCT_AAPT_CONFIG, but this target
    # can't know anything about PRODUCT.  Clear it out just for this target.
    $(resource_export_package): PRIVATE_PRODUCT_AAPT_CONFIG :=
    $(resource_export_package): PRIVATE_PRODUCT_AAPT_PREF_CONFIG :=
    $(resource_export_package): PRIVATE_RESOURCE_LIST := $(all_res_assets)
    $(resource_export_package): $(all_res_assets) $(full_android_manifest) $(rs_generated_res_zip) $(AAPT)
    @echo "target Export Resources: $(PRIVATE_MODULE) ($@)"
    $(create-empty-package)
    $(add-assets-to-package)
  endif

$(LOCAL_BUILT_MODULE): $(R_file_stamp)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

LOCAL_BUILT_MODULE做的动作有create-empty-package、add-assets-to-package、add-jni-shared-libs-to-package、add-dex-to-package、add-carried-java-resources、add-java-resources-to-package、sign-package、align-package等等。

$(LOCAL_BUILT_MODULE): PRIVATE_DONT_DELETE_JAR_DIRS := $(LOCAL_DONT_DELETE_JAR_DIRS)
$(LOCAL_BUILT_MODULE): PRIVATE_RESOURCE_INTERMEDIATES_DIR := $(intermediates.COMMON)/resources
$(LOCAL_BUILT_MODULE): PRIVATE_FULL_CLASSES_JAR := $(full_classes_jar)
$(LOCAL_BUILT_MODULE) : $(jni_shared_libraries)
$(LOCAL_BUILT_MODULE) : $(JAR_ARGS)
ifdef LOCAL_USE_AAPT2
$(LOCAL_BUILT_MODULE): PRIVATE_RES_PACKAGE := $(my_res_package)
$(LOCAL_BUILT_MODULE) : $(my_res_package) $(AAPT2) | $(ACP)
else
$(LOCAL_BUILT_MODULE): PRIVATE_RESOURCE_LIST := $(all_res_assets)
$(LOCAL_BUILT_MODULE) : $(all_res_assets) $(full_android_manifest) $(AAPT) $(ZIPALIGN)
endif  # LOCAL_USE_AAPT2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

好了经过这么一些套路的操作,大家应该知道其实product的影响是编译的时候根据TARGET_AAPT_CHARACTERISTICS来改变aapt打包时候决定的。这个流程有点繁琐,大家可以根据各自的Android版本自行研究。

build/make/core/package_internal.mk:353:$(R_file_stamp) $(my_res_package): PRIVATE_TARGET_AAPT_CHARACTERISTICS := $(TARGET_AAPT_CHARACTERISTICS)
  • 1

2.3 验证一把

下面我们将device下面的device/qcom/msm8953_64/msm8953_64.mk的PRODUCT_CHARACTERISTICS修改为tablet,如下所示:

diff --git a/device/qcom/msm8953_64/msm8953_64.mk b/device/qcom/msm8953_64/msm8953_64.mk
index c785f37..6c55481 100755
--- a/device/qcom/msm8953_64/msm8953_64.mk
+++ b/device/qcom/msm8953_64/msm8953_64.mk
@@ -113,7 +113,7 @@ DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += \
     device/qcom/msm8953_64/vendor_framework_compatibility_matrix.xml
 
 # default is nosdcard, S/W button enabled in resource
-PRODUCT_CHARACTERISTICS := nosdcard
+PRODUCT_CHARACTERISTICS := tablet
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

此时我么通过make -j32 Settings重新编译Settings,然后推入终端看看终端的表现形式,就能说明是否是在编译打包时决定而不是运行时。

msm8953_64:/ # getprop  ro.build.characteristics
device
  • 1
  • 2
<string name="about_settings" product="tablet" msgid="593457295516533765">"关于平板电脑"</string>
<string name="about_settings" product="default" msgid="1743378368185371685">"关于手机"</string>
<string name="about_settings" product="device" msgid="6717640957897546887">"关于设备"</string>
<string name="about_settings" product="emulator" msgid="221313099578564438">"关于模拟设备"</string>
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述



结语

修行至此,Android xml里面product的值来自哪里以及怎么影响编译已经播讲完毕了。我想对于Android xml中product的配置各位应该可以畅通无阻,来去无踪影了。此时的你可以一剑走天下了,为师的必杀器已经倾囊相授了。各位江湖见。



写在最后

    各位读者看官朋友们,Android xml里面product的值来自哪里以及怎么影响编译?已经全部完毕,希望能吸引你,激活发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/255983
推荐阅读
相关标签
  

闽ICP备14008679号