首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

深入显出 - Android系统移植与平台开发(六)- 为Android启动加速

2012-10-23 
深入浅出 - Android系统移植与平台开发(六)- 为Android启动加速Android的启动速度一直以来是他的诟病,虽然

深入浅出 - Android系统移植与平台开发(六)- 为Android启动加速

Android的启动速度一直以来是他的诟病,虽然现在Android设备的硬件速度越来越快,但是随着新版本的出现,其启动速度一直都比较慢,当然,作为程序员,我们是可以理解的,智能手机本身就要启动很多服务来支持应用的功能,并且Android系统大部分还是使用的Java语言编写的,必然要运行在Java虚拟机里,这也决定了它运行速度和启动速度都相对较慢。同时,Android系统为了在执行用户应用程序时提高用户体验,还做了一些预加载机制,这也牺牲了开机启动时间。

根据Android启动过程的分析可知,我们可以进行定制加速如下:

?  定制本地服务

?  定制Android系统服务

?  优化ZygoteInit的类预加载preloadClasses和资源预加载preloadResources机制

?  PackageManagerService扫描、检查APK安装包信息

下面我们依次来分析其实现步骤。

 

1. 定制本地服务

由第二章,第2节可知,本地服务都是由C或C++编写,它们都执行在Linux空间,在init进程的启动过程中启动了很多本地服务,如果我们的设备中没有电话模块、蓝牙模块,我们可以将这些没用的本地服务在init.rc里注释掉。

396 #service ril-daemon /system/bin/rild

397#     class main

398#     socket rild stream 660 root radio

399#     socket rild-debug stream 660 radio system

400#     user root

401#     group radio cache inet misc audio sdcard_rw log

 

435 service dbus /system/bin/dbus-daemon --system --nofork

436     class main

437 #    socket dbus stream 660 bluetooth bluetooth

438     user bluetooth

439     group bluetooth net_bt_admin

 

441 #service bluetoothd /system/bin/bluetoothd -n

442 #    class main

443 #    socket bluetooth stream 660 bluetooth bluetooth

444 #    socket dbus_bluetooth stream 660 bluetooth bluetooth

445     # init.rc does not yet support applying capabilities, so run as root and

446     # let bluetoothd drop uid to bluetooth with the right linux capabilities

447 #    group bluetooth net_bt_admin misc

448 #    disabled

 

重新编译system.img然后启动模拟器即可。

笔者做了对比,去掉上述几个本地服务与没有去掉本地服务,二者在开机时间上几乎没有减少多少,这也可以理解,因为本地服务就是几个程序,少执行和多执行几个程序对于总体开机时间没有多大影响,不过,去掉没有使用的本地服务,对整个系统性能来说,会有微不足道的提升。

如果去掉开机动画服务可以大大的提高系统的启动速度:


 无优化时的APK总计有50个,减少APK时APK只有5个,包扫描的时间减少了4秒,Android服务启动的时间减少了近10秒,整个系统的启动时间减少了15秒左右

在减少APK的情况下,然后将开机动画关闭了,本地服务启动时间略有减少,预加载类与资源时减少了近10秒,包扫描时间减少了0.5秒左右,Android服务启动时间减少近4秒,整个系统启动时间减少了近15秒。

由此可见,减少APK的数量关闭开机动画可以明显的提高Android的启动速度。

至于关闭其它本地服务对启动时间影响不大的原因,我的感觉是本地服务注册到Binder之后就等待框架客户端的连接,而关闭开机动画对启动速度影响之大,通过分析bootanim可知,在开启动画时要开启一个线程,mask图片在前面作为幕布,shine图片在后面每隔一定时间重新绘制一次,每次绘制时通过调用OPENGL的api调用2D加速来绘制图片,而我们使用的模拟器,全部操作通过软件来模拟,所以对系统怕启动速度影响比较大。如果在具体的设备上执行对启动速度的影响应该比这要小,具体硬件设备上优化,后续会有博文推出。


4. Android系统企业级定制

在做Android产品开发的过程中,经常会有客户说:“我们不想让我们的产品开机后看到Android系统的桌面,我们希望设备开机会直接进入我们自己的程序“。“我们的产品就是直接面对最终用户的,其它的无关的功能不需要。”比如说,之前我们开发的一款社区医疗软件,通过蓝牙和心电仪、血糖仪等采集外设通信,客户要求开机进入医疗软件,通过底层蓝牙通信,我们采用的就是定制的Android平板的桌面。

通常定制应用程序开机启动有两种实现方式:

?  接收系统启动广播:BOOT_COMPLETED,在广播接收器代码里实现应用程序的启动。

?  编写一个桌面程序,替换掉系统默认的Launcher应用。

第一种方式实现简单,但是这个应用程序是在Android系统桌面出现之后再启动的,不是真正意义上的产品定制,并且,如果当前的应用程序崩溃了退出后,会回到桌面上,当然我们可以实现崩溃后再次重新启动,但是,这终究不是真正意义上的定制。

第二种实现方式思路:当系统启动完毕之后,系统会发出一个Action为android.intent.action.MAIN,category为android.intent.category.HOME的Intent,默认系统的Launcher桌面会响应这个Intent,那么,我们可以编写一个应用程序,让它去响应这个Intent,然后我们将这个应用程序替换掉系统默认的Launcher桌面。系统重新启动之后,会自动启动我们自己的应用。但是,如果一些非法程序也响应这个Intent,那么照样不能达到客户的目的。这个时候,我们就要去修改系统框架代码,让Android系统启动完毕之后发送我们自己定义的Intent而不是公开的category为HOME的 Intent。

思路如下:

?  添加一个新的category:android.intent.category.FS_HOME

?  将框架里面所有发送android.intent.category.HOME的Intent全部改成android.intent.category.FS_HOME

category的定义文件在:

frameworks/base/core/java/android/content/Intent.java

2218     /**

2219      * This is the home activity, that is the first activity that is displayed

2220      * when the device boots.

2221      */

2222     @SdkConstant(SdkConstantType.INTENT_CATEGORY)

2223     public static final String CATEGORY_HOME = "android.intent.category.HOME";

 

在CATEGORY_HOME后面添加下面两行代码:

2224     @SdkConstant(SdkConstantType.INTENT_CATEGORY)

2225     public static final String CATEGORY_FS_HOME = "android.intent.category.FS_HOME";

 

通过grep CATEGORY_HOME frameworks/ -R命令查找所有使用CATEGORY_HOME的文件:

./frameworks/ex/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java

./frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

./frameworks/base/services/java/com/android/server/am/ActivityRecord.java

./frameworks/base/services/java/com/android/server/UiModeManagerService.java

./frameworks/base/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java

./frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

./frameworks/base/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java

 

将文件里使用CATEGORY_HOME常量的地方全部改为CATEGORY_FS_HOME。

新建一个Android应用:MyLauncher,在其AndroidManifest.xml里,<intent-filter>标签里添加上响应CATEGORY_FS_HOME的代码:

<activity android:name=".MyLauncherActivity">

        <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.FS_HOME" />

                   <category android:name="android.intent.category.DEFAULT" />

        </intent-filter>

</activity>

 

重新编译frameworks/base、frameworks/ex:

$ source build/envsetup.sh

$ make

重新运行模拟器,使用新编译的Android系统,可以看到系统启动起来就进入我们的MyLauncher应用,从实现实现桌面的替换。

 深入显出 - Android系统移植与平台开发(六)- 为Android启动加速

 

热点排行