处理Android应用资源定制的不完全记录

| 分类 Android  | 标签 安卓系统  招式 

零、存在背景

最近有个客户定制翻译和图片资源的需求。

这个定制修改的范围不仅局限于我们自研的app,还有framwork上的一些资源文件,甚至包括定制第三方app比如XX商店的名字等。前两者还在我们的控制内,最后一个就体现了我大天朝的SZ特色了。

一、解决方案

1、根据属性加载不同的资源文件

这个需要将所有用到的资源都打包到apk里面,再根据属性去判断加载不同的文件。这个会使apk大小加大,而且维护成本高。而且最后一个不满足。

2、类似应用换肤功能

因为我们launcher已经做了定制皮肤的需求,问了相关同事用了这个方法,可以满足上面提到的前两个情况。但是需要修改之前的app源码。根据实际项目情况,也不适合。而且最后一个不满足。

  • 优势是不需要系统权限
  • 劣势是需要修改被定制的app代码

3、Runtime Resource Overlay

后面了解到在android 5.1之后有一个RRO机制。可以满足上面的要求。

  • 优势是不需要修改被定制的app代码
  • 劣势是需要ROM的控制权,也就是要有root权限,而且system能挂载读写

二、RRO介绍

这篇文章 介绍了这个功能是SONY工程师 Mårten Kongstad 开发,并提交到AOSP上的。

In Android apps, resources are additional files that contain integers, strings, bitmaps, and layout definitions, etc. to be used by the Java code. Since resources are externalized from the application code, an Android app can change its look and feel dynamically depending on the device current configuration such as the user locale, screen size or orientation, because the app accesses its resources by referencing the resource IDs, and Android has implemented a resource lookup system that uses the current device configuration to map a resource ID to the compiled binary blob of the best-match resource amongst all alternative resources.

Android resource lookup with RRO feature

如上图,新添加一个Overlay APK,把定制的资源文件放进去,Resource Lookup那么会先加载Overlay APK的资源。

三、RRO使用

使用很简单,只需要overlayApp即可。demo地址

1、targetApp

假设被替换目标app如下

布局文件
<TextView
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="@string/hello_world" />
资源文件
<resources>
    <string name="app_name">RRO Target</string>
    <string name="hello_world">Hello World. notice: from Target!</string>
</resources>

2、overlayApp

我们要替换hello_world字符串时需要新建一个工程

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.linxtu.rro.overlay">

    <overlay
        android:priority="1"
        android:targetPackage="com.linxtu.rro.target" />

</manifest>

notice:有些资源文件是在framework下的,android:targetPackage为android

资源文件
<resources>
    <string name="app_name">RRO Target</string>
    <string name="hello_world">Hello World. notice: from Overlay!</string>
</resources>
推进系统

放到 /system/vendor/overlay/下,重启即可。

四、RRO原理分析 (TODO)

因为一开始在海思Android5.1平台上RRO是没跑通的,在网上查了应该是当时海思从谷歌拉代码时功能还没全部OK,网上找了下需要合入以下patch。

  • https://android-review.googlesource.com/#/c/113651/
  • https://android-review.googlesource.com/#/c/113652/
  • https://android-review.googlesource.com/#/c/113653/

还有一个问题这套机制需要在Android5.1才可以,但是现在维护的方案还有很多是4.4版本,接下来还需要看下实现,有没有可能在4.4导入这套东东

SEE U NEXT TIME


上一篇     下一篇