Android换肤方案分析

简介: ## 0x0 背景 无论是出于用户个性化的考虑,或者是不同场景下的氛围渲染,客户端应用存在着换肤的需求。本文举出三种常见的换肤方案,并加以对比,以作后续参考。无论何种方案,换肤的核心都包含皮肤的管理,皮肤的加载,以及皮肤的生效。不同的方案在解决这些问题上有不同的思路。 ## 0x1 手动重新设置UI资源 这种方式最简单,在业务代码里面手动写设置新皮肤的逻辑,当新皮肤下发时,回调该逻辑重新

0x0 背景

无论是出于用户个性化的考虑,或者是不同场景下的氛围渲染,客户端应用存在着换肤的需求。本文举出三种常见的换肤方案,并加以对比,以作后续参考。无论何种方案,换肤的核心都包含皮肤的管理,皮肤的加载,以及皮肤的生效。不同的方案在解决这些问题上有不同的思路。

0x1 手动重新设置UI资源

这种方式最简单,在业务代码里面手动写设置新皮肤的逻辑,当新皮肤下发时,回调该逻辑重新设置UI资源,就达到了换肤的逻辑。这种方案思路简单,但是业务入侵的,需要手动写代码,有维护成本。而且由于需要手动写重新设置UI的逻辑,因此一般不会对所有的控件都更换UI资源,因此换肤的范围存在局限性。

public void onSkinChanged(JSONObject newSkin) {
    int newTextColor = newSkin.optInt("my_text_color");
    TextView myTextView = (TextView)findViewById("R.id.mytext");
    myTextView.setTextColor(newTextColor);

    String newImageUrl = newSkin.optString("my_img_url");
    UrlImageView myImageView = (UrlImageView)findViewById("R.id.myimage");
    myImageView.setImageUrl(newImageUrl);
}

0x2 自定义资源框架

Android原生的资源都是通过Resources加载定义在res目录下的xml中的资源。由于res目录下的资源是随打包发布的,因此无法做到动态替换。所以这里的思路是自定义一个CustomResources,并自定义resources目录,里面区分default,night, custom等等。default目录下是默认资源,其他目录下是特定场景的皮肤资源,其id和default目录保持一致,就可以实现替换。

resources
    |--- default
            |--- res
            |--- drawable
    |--- night
            |--- res
            |--- drawable

CustomResources可以加载APK包里面的默认资源,也可以加载从服务端下发的资源。在应用开发过程中,不能再使用系统的Resources,必须使用CustomResources,否则无法实现换肤。

    TextView myTextView = (TextView)findViewById("R.id.mytext");
    myTextView.setTextColor(getCustomResrouce().getColor(R.color.mytextcolor));

当然至此为止还不能cover布局xml中直接使用资源id的场景,如果要cover,需要hook系统resources。这种方式需要在应用开发之初就有换肤的设计,开发团队内部约定统一用CustomResources而不用系统的资源。

0x3 Hook系统LayoutInflater

这种思路是hook系统的LayoutInflater,在解析布局xml生成View的时候,替换成继承了换肤逻辑的子类。ximsfei/Android-skin-support是这种思路的代表。替换LayoutInflater的方式是:

   private void installLayoutFactory(Context context) {
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        try {
            Field field = LayoutInflater.class.getDeclaredField("mFactorySet");
            field.setAccessible(true);
            field.setBoolean(layoutInflater, false);
            LayoutInflaterCompat.setFactory(layoutInflater, getSkinDelegate(context));
        } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

ximsfei/Android-skin-support的实现方案中,下发皮肤其实是在一个只包含资源文件的APK文件中,保证资源APK中的资源命名和默认的保持一致就能实现替换。读取APK文件中的资源的方式是:

    public Resources getSkinResources(String skinPkgPath) {
        try {
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, skinPkgPath);

            Resources superRes = mAppContext.getResources();
            return new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

这种方式对于应用开发者来说几乎是透明的,对于业务也没有侵入性,尤其是已有的应用代码上迭代增加换肤功能,这是一种比较好的方式。

目录
相关文章
|
23天前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
18 1
|
2月前
|
Android开发 数据安全/隐私保护 iOS开发
安卓与iOS系统的发展趋势与比较分析
【2月更文挑战第6天】 在移动互联网时代,安卓和iOS系统作为两大主流移动操作系统,各自呈现出不同的发展趋势。本文将从技术角度出发,对安卓和iOS系统的发展方向、特点及未来趋势进行比较分析,以期为读者提供更深入的了解和思考。
33 4
|
3月前
|
监控 Android开发 C语言
深度解读Android崩溃日志案例分析2:tombstone日志
深度解读Android崩溃日志案例分析2:tombstone日志
81 0
|
3月前
|
数据安全/隐私保护 Android开发
2023安卓逆向 -- 某合伙apk登录加密分析
2023安卓逆向 -- 某合伙apk登录加密分析
24 0
|
7月前
|
Java Android开发
Android oom pthread_create (1040KB stack)分析及解决
Android oom pthread_create (1040KB stack)分析及解决
84 0
|
2月前
|
网络协议 算法 Android开发
安卓逆向 -- 实战某峰窝APP(动态分析)
安卓逆向 -- 实战某峰窝APP(动态分析)
24 4
|
2月前
|
安全 搜索推荐 Android开发
Android 与 iOS 的比较分析
【2月更文挑战第5天】 Android 和 iOS 是目前市场上两种最流行的移动操作系统,它们都拥有自己的特点和优势。本文将会分别从操作系统设计、应用生态、安全性等方面对这两种操作系统进行比较和分析,希望能够帮助读者更好地选择适合自己的移动设备。
|
3月前
|
安全 算法 JavaScript
安卓逆向 -- 关键代码定位与分析技术
安卓逆向 -- 关键代码定位与分析技术
39 0
|
3月前
|
算法 安全 Android开发
安卓逆向 -- Frida Hook某车_sign算法分析
安卓逆向 -- Frida Hook某车_sign算法分析
76 0
|
3月前
|
安全 Android开发 数据安全/隐私保护
安卓逆向 -- SO文件逆向分析
安卓逆向 -- SO文件逆向分析
19 0