有關android加快開機速度
我們知道,android開機速度慢,在恢復出廠設定後開機速度更慢,其中優化dex檔案的過程就耗時很多。那麼我們就可以嘗試將優化dexopt步驟提前到編譯階段生成img檔案的環節去。當然了這是一個以rom空間換取時間的策略。
可以通過在BoardConfig.mk中加入
# Enable the optimized DEX
WITH_DEXPREOPT=true
或者直接修改system.prop
# ODEX
dalvik.vm.verify-bytecode=true
然後我們探索看看android是怎麼樣進行這個特性的?
$grep -r "WITH_DEXPREOPT" build/
build/core/prebuilt.mk:ifeq (true,$(WITH_DEXPREOPT))
build/core/java_library.mk:ifeq (true,$(WITH_DEXPREOPT))
build/core/main.mk: ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)
build/core/main.mk: WITH_DEXPREOPT := true
build/core/package.mk:ifeq (true,$(WITH_DEXPREOPT))
build/core/product_config.mk: WITH_DEXPREOPT_buildbot := true
在build/core下面有個檔案dex_preopt.mk,這個檔案值得注意。
android真是太龐大了,其指令碼之間的關係對於我這個初涉的人還是好生畏懼,值得研究。詳細如下。
======================================================
build/core/main.mk
# config/product_config.make once host-based Dalvik preoptimization is
# working.
ifneq (true,$(DISABLE_DEXPREOPT))
ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)
WITH_DEXPREOPT := true
endif
endif
=====================================================
build/core/package.mk
ifeq (true,$(WITH_DEXPREOPT))
ifeq (,$(TARGET_BUILD_APPS))
ifneq (,$(LOCAL_SRC_FILES))
ifndef LOCAL_DEX_PREOPT
LOCAL_DEX_PREOPT := true
endif
endif
endif
endif
=====================================================
build/core/prebuild.mk
ifneq ($(filter APPS,$(LOCAL_MODULE_CLASS)),)
ifeq (true,$(WITH_DEXPREOPT))
ifeq (,$(TARGET_BUILD_APPS))
ifndef LOCAL_DEX_PREOPT
LOCAL_DEX_PREOPT := true
endif
endif
endif
endif
=====================================================
build/core/java_library.mk
ifeq (true,$(WITH_DEXPREOPT))
ifeq (,$(TARGET_BUILD_APPS))
ifndef LOCAL_DEX_PREOPT
LOCAL_DEX_PREOPT := true
endif
endif
endif
====================================================
build/core/product_config.mk
# Hack to make the linux build servers use dexpreopt (emulator-based
# preoptimization). Most engineers don't use this type of target
# ("make PRODUCT-blah-user"), so this should only tend to happen when
# using buildbot.
# TODO: Remove this once host Dalvik preoptimization is working.
ifeq ($(TARGET_BUILD_VARIANT),user)
WITH_DEXPREOPT_buildbot := true
endif
另外補充:
1、system/app下放置系統apk;data/app下放置內建第三方apk;
2、在生成的system/app和system/framework下會生成優化後的odex檔案;
3、odex佔用物理空間比dex和apk檔案要大,所以上述方法是計算機作業系統中典型的空間和時間互換的思想;
下面的轉自:http://www.cnblogs.com/jacobchen/p/3599483.html
BOOTCLASSPATH簡介
1.BOOTCLASSPATH是Android Linux的一個環境變數,可以在adb shell下用$BOOTCLASSPATH看到。
2.BOOTCLASSPATH於/init.rc檔案中export,如果沒有找到的話,可以在init.rc中import的檔案裡找到(如import /init.environ.rc)。
3.init.rc檔案存在於boot.img的ramdisk映像中。如果僅僅是修改/init.rc檔案,重啟後會被ramdisk恢復,所以直接修改是沒有效果的。
4.boot.img是一種特殊的Android定製格式,由boot header,kernel,ramdisk以及second stage loader(可選)組成,詳見android/system/core/mkbootimg/bootimg.h。
boot.img空間結構:
** +-----------------+
** | boot header | 1 page
** +-----------------+
** | kernel | n pages
** +-----------------+
** | ramdisk | m pages
** +-----------------+
** | second stage | o pages
** +-----------------+
典型的ramdisk檔案結構:
./init.trout.rc
./default.prop
./proc
./dev
./init.rc
./init
./sys
./init.goldfish.rc
./sbin
./sbin/adbd
./system
./data
BOOTCLASSPATH的作用
以Android4.4手機的BOOTCLASSPATH為例:
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar...
當kernel啟動時1號程序init解析init.rc,將/system/framework下的jar包路徑export出來。
Dalvik虛擬機器在初始化過程中,會讀取環境變數BOOTCLASSPATH,用於之後的類載入和優化。
Dalvik虛擬機器的啟動和dexopt流程
從一文可以知道,Zygote會在啟動後建立Dalvik虛擬機器例項,並進行初始化。
那我們就接著Dalvik虛擬機器初始化後開始探究它是如何通過BOOTCLASSPATH來進行dex優化的:
1.1. VM initialization
android/dalvik/vm/Init.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 |
std::string
dvmStartup( int argc,
const char *
const argv[],
bool ignoreUnrecognized,
JNIEnv* pEnv)
{
...
ALOGV( "VM
init args (%d):" ,
argc);
...
setCommandLineDefaults();
//
---> 讀取BOOTCLASSPATH
...
if (!dvmClassStartup())
{ //
---> 初始化bootstrap class loader
return "dvmClassStartup
failed" ;
}
}
|
1.2. 讀取BOOTCLASSPATH
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
static void setCommandLineDefaults()
{
const char *
envStr = getenv ( "CLASSPATH" );
if (envStr
!= NULL) {
|