Android 優化開機啟動


Android開機啟動慢,是一個眾所周知的問題。

優化方向:

1、預加載的優化

在網上看的資料,對於開機啟動來說,耗時最久的是preload classes和scan packages。所以第一個優化方向就是預加載類。
這是在網上看的

· preloaded-classes list中預加載的類位於dalvik zygote進程的heap中。在zygote衍生一個新的dalvik進程后,新進程只需加載heap中沒有預加載的類(這些后加載進來的類成為該進程所private獨有的),這樣便加快了應用程序的啟動速度。實際上這是一種以空間換時間的辦法,因為幾乎沒有一個應用程序能夠使用到所有的預加載類,必定有很多類對於該應用程序來說是冗余的。但是也正如Google所說,智能手機開機遠沒有啟動應用程序頻繁——用戶開機一次,但直到下次再開機之前可能要運行多個應用程序。因此犧牲一點啟動時間來換取應用程序加載時的較快速度是合算的。

· preloaded-classes list已經是Google Android工程師使用眾多測試工具分析,加以手動微調后形成的最優化預加載列表,涵蓋了智能機上最長見的應用類型所需要的各種類。很難想象我們自己能夠有什么手段能夠獲得比這樣更優的一個預加載列表。所以,除非你的Android系統是被移植到非智能手機設備上使用(例如MID、EBOOK,可以不需要Telephony相關的類),不建議去“優化”preloaded-classes list。 在zygote中單起一個線程來做preload,是否可行?答案是否定的。首先在zygote中不可以新開線程,其次,就算新開一個線程,在目前智能機硬件條件下(單核CPU),除非有頻繁大量的存儲IO,否則我們不能看到我們期望加速啟動效果。

上面說了“但是也正如Google所說,智能手機開機遠沒有啟動應用程序頻繁——用戶開機一次,但直到下次再開機之前可能要運行多個應用程序。因此犧牲一點啟動時間來換取應用程序加載時的較快速度是合算的。”但是對於機頂盒來說,這就反而不是這樣了,機頂盒的開關機比較頻繁。

預加載優化方向:
(1)、將預加載放置到system_server 啟動之后。
對於幾個preload來說,最耗時的是類的預加載,所以我們可以把
preloadclass單獨剝離出來一個線程,並將其放到system_server之后,會有一定的啟動速度提升。
如此下代碼所示:

    public static class PreloadClassThread extends Thread {
public void run() {
preloadClasses();
}
}

static void preload() {
// preloadClasses(); // Delay preloadClasses
preloadResources();
preloadOpenGL();
}

public static void main(String argv[]) {
try {

.....省略無關代碼
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());

.....省略無關代碼


if (argv[1].equals("start-system-server")) {
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}

Log.i(TAG, "Accepting command socket connections");

Thread preloadclass = new PreloadClassThread();
preloadclass.start();

(2)、加載的時候要順序加載 ,我們可以改為多線程同步來執行。
preloadClasses();
preloadResources();
preloadOpenGL();
android 原本的加載方式如下:

 static void preload() {
preloadClasses();
preloadResources();
preloadOpenGL();
}

我們修改為:

    static void concurrent_preload() {
Thread preloadclass = new PreloadClassThread();
Thread preloadres = new PreloadResThread();

preloadclass.start();
preloadres.start();

try {
preloadclass.join();
preloadres.join();
} catch (InterruptedException ex) {
Log.e(TAG, "concurrent_preload join() InterruptedException error ", ex);
}

preloadOpenGL();
}

我們可以加一些屬性來控制是否要跳過預加載、選擇哪種方式預加載。
scan packages的優化就是減少不必要的APK了。

2、去除SELinux

SELinux是一種強制訪問控制(MAC)系統。有以下兩種模式:
Enforcing:使能狀態,所有違反policy的動作都會被拒絕。
Permissive:寬容模式,違反policy的動作不會被拒絕,只會警告。
開啟SELinux,在kernel和init進程都會有相關的一些操作,所以會對開機速度有一定的影響。如果對於機頂盒這種的話,其實看情況也是可以關掉的。
關閉方法對於各個廠商可能有些不同,一般是在bootargs里面把其配置為關閉即可。

3、開機動畫

其實很多時候,盒子已經到了launcher啟動的階段,但是開機動畫還沒播放完。優化開機動畫的顯示時間,可以減少很多開機時間,但是出於盒子本身的功能來說,開機動畫一般用作廣告,所以這個可以優化的空間比較小。手機倒是可以這樣子優化,這就沒什么好說的了,修改bootanimation.zip中的開機動畫時間即可。

4、減少不必要的service

這里說的是兩種不同概念的service:
1是由init進程來啟動的service,這個需要裁剪init.xxx.rc中不需要的service,因為init進程啟動太多service的話,可能會導致zygote和systemServer啟動速度受到影響。
2是system_server啟動的java層面的service,像機頂盒的話telephony,location這樣的服務一般也可以不要了。

5、修改為odex方式

這是以空間換取時間的優化方式。

1、在自己device目錄 下Bordconfig.mk中加入

WITH_DEXPREOPT=true

2、在相同目錄下修改system.prop

dalvik.vm.verify-bytecode=true


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com