点击打开链接

BOOTCLASSPATH被赋值流程分析

system/core/rootdir/init.environ.rc.in

# set up the global environment
on initexport PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbinexport LD_LIBRARY_PATH /vendor/lib:/system/libexport ANDROID_BOOTLOGO 1export ANDROID_ROOT /systemexport ANDROID_ASSETS /system/appexport ANDROID_DATA /dataexport ANDROID_STORAGE /storageexport ASEC_MOUNTPOINT /mnt/asecexport LOOP_MOUNTPOINT /mnt/obbexport BOOTCLASSPATH %BOOTCLASSPATH%
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

通过上面的代码我们知道BOOTCLASSPATH环境变量等于%BOOTCLASSPATH%,那%BOOTCLASSPATH%是谁赋的值呢?往下看。

system/core/rootdir/Android.mk

$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/init.environ.rc.in FORCE@echo "Generate: $< -> $@"@mkdir -p $(dir $@)$(hide) sed -e 's?%BOOTCLASSPATH%?$(PRODUCT_BOOTCLASSPATH)?g' $< >$@
  • 1
  • 2
  • 3
  • 4

语法解释

FORCE 表示目标文件每次编译的时候都会重新生成$< 表示依赖文件, 即$(LOCAL_PATH)/init.environ.rc.in, 等于system/core/rootdir/init.environ.rc.in$@ 表示目标文件, 即$(LOCAL_BUILT_MODULE), 等于out/target/product/imx6/obj/ETC/init.environ.rc_intermediates/init.environ.rc$(hide) = @, @加命令 表示只显示命令结果, 不显示命令本身sed -e 's?%BOOTCLASSPATH%?$(PRODUCT_BOOTCLASSPATH)?g' $< > $@
这条命令表示将$<文件里面的%BOOTCLASSPATH%替换为$(PRODUCT_BOOTCLASSPATH),并将结果输出到$@中。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

通过对上面这个mk文件的分析,我们知道%BOOTCLASSPATH%将被$(PRODUCT_BOOTCLASSPATH)替换掉,那$(PRODUCT_BOOTCLASSPATH)又是谁赋值的呢?继续往下分析。先看下hide被赋值的地方。

ndk/build/core/definitions.mk

# -----------------------------------------------------------------------------
# Macro    : hide
# Returns  : nothing
# Usage    : $(hide)<make commands>
# Rationale: To be used as a prefix for Make build commands to hide them
#            by default during the build. To show them, set V=1 in your
#            environment or command-line.
#
#            For example:
#
#                foo.o: foo.c
#                -->|$(hide) <build-commands>
#
#            Where '-->|' stands for a single tab character.
#
# -----------------------------------------------------------------------------
ifeq ($(V),1)
hide = $(empty)
else
hide = @
endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

hide的赋值就不多说了,主要看下PRODUCT_BOOTCLASSPATH是怎么被赋值的。

build/core/dex_preopt.mk

DEXPREOPT_BOOT_JARS := $(PRODUCT_BOOT_JARS)
DEXPREOPT_BOOT_JARS_MODULES := $(subst :, ,$(DEXPREOPT_BOOT_JARS))
PRODUCT_BOOTCLASSPATH := $(subst $(space),:,$(foreach m,$(DEXPREOPT_BOOT_JARS_MODULES),/system/framework/$(m).jar))
  • 1
  • 2
  • 3

语法解释

$(foreach VAR, LIST, TEXT) 表示将LIST中以空格分割的单词赋值给VAR,然后执行TEXT表达式,TEXT可能存在对VAR的引用。返回以空格分割的TEXT的执行结果。$(subst FROM,TO,TEXT) 表示把字串TEXT中的FROM字符替换为TO。返回替换后的新字符串。
  • 1
  • 2
  • 3

通过上面两个语法的分析,我们知道DEXPREOPT_BOOT_JARS_MODULES会将DEXPREOPT_BOOT_JARS里的:替换为空格。然后PRODUCT_BOOTCLASSPATH会将DEXPREOPT_BOOT_JARS_MODULES里的值轮询,并赋值给到/system/framework/x.jar,最后将这些.jar之间的空格替换会:。所以PRODUCT_BOOTCLASSPATH最终的显示值应该是/system/framework/x.jar:/system/framework/y.jar:/system/framework/z.jar类似这样的形式。PRODUCT_BOOT_JARS又是在哪赋值的呢?

build/target/product/core_base.mk

PRODUCT_BOOT_JARS := core:conscrypt:okhttp:core-junit:bouncycastle:ext:framework:framework2:telephony-common:voip-common:mms-common:android.policy:services:apache-xml:webviewchromium
  • 1

小节

通过上面的分析,我们知道BOOTCLASSPATH的赋值其实是通过PRODUCT_BOOT_JARS来的。如果我们想添加自定义的jar包,我们只需要在PRODUCT_BOOT_JARS添加相应的jar就行了。

实战操作

1.将相关自定义的java文件编译到自定义模块

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_SRC_FILES := \$(call all-java-files-under, java) \LOCAL_MODULE:= custom
LOCAL_MODULE_TAGS := optional# List of classes and interfaces which should be loaded by the Zygote.
include $(BUILD_JAVA_LIBRARY)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这样我们自定义的custom.jar就会被编译到/system/framework/custom.jar中。

2.将自定义模块编译到系统中

接下来我们需要系统在编译的时候能将custom.jar模块编译到系统中。我们需要添加如下代码:

device/xxx/yyy.mk

PRODUCT_PACKAGES += custom
  • 1

3.在PRODUCT_BOOT_JARS中添加自定义模块

build/target/product/core_base.mk

PRODUCT_BOOT_JARS := core:conscrypt:okhttp:core-junit:bouncycastle:ext:framework:framework2:telephony-common:voip-common:mms-common:android.policy:services:apache-xml:webviewchromium:custom
  • 1

通过上面的3步,就可以将custom.jar编译到/system/framewrok/custom.jar中。同时,在BOOTCLASSPATH中也添加了custom.jar。

4.验证BOOTCLASSPATH是否添加了自定义模块

在PC端使用adb shell $BOOTCLASSPATH就可以查看BOOTCLASSPATH的值了。

C:\Users\Steven>adb shell $BOOTCLASSPATH
/system/bin/sh: /system/framework/core.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/webviewchromium.jar:/system/framework/custom.jar: not found
  • 1
  • 2

上面我们可以到custom.jar成功添加到了BOOTCLASSPATH中,大功告成!

Android BOOTCLASSPATH详解相关推荐

  1. 【转】Android菜单详解——理解android中的Menu--不错

    原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...

  2. Android菜单详解——理解android中的Menu

    前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...

  3. Android LayoutInflater详解

    Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...

  4. android Fragments详解

    android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...

  5. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

  6. android WebView详解,常见漏洞详解和安全源码(上)

    这篇博客主要来介绍 WebView 的相关使用方法,常见的几个漏洞,开发中可能遇到的坑和最后解决相应漏洞的源码,以及针对该源码的解析.  由于博客内容长度,这次将分为上下两篇,上篇详解 WebView ...

  7. android子视图无菜单,Android 菜单详解

    Android中菜单分为三种,选项菜单(OptionMenu),上下文菜单(ContextMenu),子菜单(SubMenu) 选项菜单 可以通过两种办法增加选项菜单,一是在menu.xml中添加,该 ...

  8. Android StateFlow详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121913352 本文出自[赵彦军的博客] 文章目录 系列文章 一.冷流还是热流 S ...

  9. Android SharedFlow详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121911675 本文出自[赵彦军的博客] 文章目录 系列文章 什么是SharedF ...

最新文章

  1. CVPR 2021 | 自适应激活函数ACON: 统一ReLU和Swish的新范式
  2. js 回车触发点击事件
  3. 大型网站系统架构系列:负载均衡详解(一)
  4. Maven最全教程,还有哪里对maven不解的地方看过来!
  5. Sliverlight MD5
  6. 计算机中国象棋书籍,[建议]中国的象棋永远不能被没有“思维”的电脑所代替(就目前的电脑象棋软件...
  7. java split空字符_java split函数结尾空字符串被丢弃的问题
  8. Linux Kernel Git国内镜像源
  9. SylixOS内存错误排查方法
  10. 如何在原生微信小程序中实现数据双向绑定
  11. mysql全套基础知识_mysql系列--基础知识
  12. mos 控制交流_MOS管和IGBT管的区别
  13. H264--H264解码--5
  14. 浅谈SQL注入的四种防御方法
  15. Hadoop环境搭建(6) -- 克隆
  16. 神经元模型 Hodgkin Huxley model
  17. java 定时为每月10号,Spring 定时任务如何实现每周一某个时间执行?
  18. [GNSS] GNSS原理:多模导航卫星精密定轨理论
  19. Linux查看目录busy,Linux中遇到device is busy的处理方法
  20. linux物联网项目,6个开源项目提升物联网开发效率

热门文章

  1. 009_storage.conf配置详情
  2. 029_jdbc-mysql二进制数据
  3. 006_url-pattern配置
  4. java clone 报错_创建ArrayList对象时显示CloneNotSupportedException错误
  5. swapCursor vs changeCursor, what’s the difference?
  6. ClassLoader工作机制
  7. IDEA 系列安装资料及教程
  8. vue component created没有触发_Vue 全局数据管理-Vuex
  9. svnadmin: e000002: 无法创建最上层目录_JFolder::create: 无法创建目录
  10. c语言循环程序设计教案,10 《C语言程序设计》教案 第三章 程序的控制结构(6)—循环结构 while和do while.doc...