写在前面:
本系列博文所讨论的内容主要是与大家一起讨论Recovery模式本地化显示文本的原理,以及如何使用谷歌提供的recovery_l10n工具实现定制本地化显示的文本。
导读:
首先我们来讨论Recovery模式下本地化文本的显示是如何实现的。
先看两张图,相信很多人都很熟悉,第一张是我们恢复出厂设置操作,关机重启进入recovery模式之后所看到的界面,第二张是通过按键进入recovery模式,带有选项菜单的主界面。一般来说普通用户正常的操作是不会看到第二个界面的,而在第一张图片中我们看到,在绿色小机器人下面有一行字符,这行字符就是本文的关键。
图1:恢复出厂设置-擦除数据
图2:recovery模式主界面-选项菜单
其实上面这行文本内容并不是以字符的形式显示的,而是用图片代替,如下图:
图3:本地化文本图片合成
补充一下,就是说当Recovery模式下需要显示这些文本信息的时候,会根据进入recovery模式前的系统语言来从上面这张图片中截取对应语言的文本信息,也就是说这个信息并不是直接用C语言打印输出到屏幕上的。
在Recovery模式下是不支持系统语言库的,但是recovery中文本信息本地化又是与主系统当前语言环境保持同步的,那么,在recovery模式是如何与主系统进行交互的呢?
主系统与recovery通过command文件中特定的参数进行交互的。
Framework层
首先来看framework/base/core/java/android/os/RecoverySystem.java中的代码片段:
/** RECOVERY_DIR是用来与recovery系统交互的目录,也就是说主系统与recovery系统是通过文件进行交互的. 详情可了解 bootable/recovery/recovery.c. */ private static File RECOVERY_DIR = new File("/cache/recovery"); private static File COMMAND_FILE = new File(RECOVERY_DIR, "command"); /* 安装指定的更新包并进行重启*/ public static void installPackage(Context context, File packageFile) throws IOException { String filename = packageFile.getCanonicalPath()//得到更新包路径 ...... final String filenameArg = "--update_package=" + filename;//将更新包路径作为参数传递写入Command文件 final String localeArg = "--locale=" + Locale.getDefault().toString();//本地化参数 bootCommand(context, filenameArg, localeArg);//重启,并将参数写入command文件 } /*擦除data和cache分区的数据并重启*/ public static void rebootWipeUserData(Context context, boolean shutdown, String reason) throws IOException { ...... String shutdownArg = null; if (shutdown) { shutdownArg = "--shutdown_after"; } String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } final String localeArg = "--locale=" + Locale.getDefault().toString();//本地化参数 bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } /*擦除cache分区的数据并重启*/ public static void rebootWipeCache(Context context, String reason) throws IOException { ...... final String localeArg = "--locale=" + Locale.getDefault().toString();//本地化参数 bootCommand(context, "--wipe_cache", reasonArg, localeArg); } /*重启进入recovery模式,并根据指定的参数指定相对应的操作,如安装更新,擦除用户数据等*/ private static void bootCommand(Context context, String... args) throws IOException { RECOVERY_DIR.mkdirs(); // In case we need it COMMAND_FILE.delete(); // In case it's not writable LOG_FILE.delete(); /*向command文件中写入指定的参数*/ FileWriter command = new FileWriter(COMMAND_FILE); try { for (String arg : args) { if (!TextUtils.isEmpty(arg)) { command.write(arg); command.write("\n"); } } } finally { command.close(); } // Having written the command file, go ahead and reboot PowerManager pm=(PowerManager)context.getSystemService(Context.POWER_SERVICE); pm.reboot(PowerManager.REBOOT_RECOVERY); throw new IOException("Reboot failed (no permissions?)"); }
从上面代码告诉我们,主系统是通过COMMAND_FILE文件的形式与recovery进行交互,根据不同的命令行参数执行不同的操作,如系统升级、恢复出厂设置等。
时间: 2024-11-09 05:53:31