Ranger Skin 安卓应用换肤的最佳实践

简介

一款安卓原生应用换肤框架。基于安卓View绘制原理和主流LayoutInflaterCompat.setFactory2 方案,使用kotlin协程+flow进行封装,对View属性 进行AOP定制

RangerSkin可运用于手机、车机等全场景安卓生态换肤方案的现。历经百天内存性能压测,几乎不存在内存和CPU额外负载消耗。愿为行业内现行换肤方案的最佳实践

优势

  • 皮肤包可工程独立。出色的项目安全和稳定性,对原工程侵入小,几乎没有改造风险
  • 采用增量订制的方式,项目适配改动工作小,支持项目分期适配
  • API极简,功能强大,涵盖几乎所有原生换肤定制场景
  • 支持minifyEnabled和shrinkResources
  • 性能的极致要求,充分验证,开发者无需关注内存泄漏等性能风险

方案对比

想要了解换肤方案和主流实践的同学请移步对 Android 应用换肤方案的总结,文章已经进行较为深度的对比总结,且文中提过的框架早已不再维护,作者认为没有可比性,在此不再进行赘述。前期设计和研发SDK借鉴了文章中提到的主要的细节的点尤其是各方案的不足,并在RangerSkin中进行补充完善。在此对文章作者开发者如是说以及相关方案框架的作者表示感谢。

接入流程

  1. 集成
    SDK版本要求和注意事项: 安卓21及以上,Kotlin1.4及以上版本(项目中如果不存在Kotlin可以不用关注)。
kotlin 复制代码
repositories {
    mavenCentral()
}
kotlin 复制代码
dependencies {
    implementation "io.github.rangerleoio.rangerskin:skin-lite:1.0.0" //请及时同步最新Release SDK版本
}
  1. 适配流程

流程图


属性支持列表

background src textColor textSize
text hint textColorHint textCursorDrawable
tint foregroundTint backgroundTint style和?attr
  1. 制作皮肤包
      RangerSkin是通过替换同名资源 设置View的属性的方式实现,因此换肤锚点 在于XML中引用资源文件名称 (以此类推,在复杂的场景中只要能满足该条件即可实现换肤功能,方便开发者自行进行场景化定制)。与此同时,SDK的加载方案是增量设计 的,即SDK会优先加载皮肤包的资源如果没有则会使用原有资源。请认真阅读此段描述,敲黑板~~~。

如图:res-c01为将要制作的主题资源文件夹。以动画资源left_out.xml为例。主题包中的资源名称与应用中的名称必须保持一致。皮肤制作的工作只要修改res-c01中left_out.xm的内容使之成为皮肤包需要的样式即可。(该示例为主工程和皮肤包工程同工程实例,建议为不同工程)

对于皮肤工程提供gradle脚本支持,用于规范和简化打皮肤包流程:

kotlin 复制代码
def ignoreTasks = ['kotlin', 'java', 'aidl', 'java', 'dex', 'kapt', 'dataBinding', 'annotationProcessor', 'ksp','apklistingfileredirect'] //皮肤包res路径
def skinRes = ['src/main/res-c01'] //皮肤包res路径
def skinName = 'CO1' //皮肤包名称
android {  
    if (isSkinPackage.toBoolean()) {  
        sourceSets.main {  
            res.srcDirs = skinRes
            manifest.srcFile 'src/main/AndroidManifest2.xml'
        }  
        tasks.configureEach { task ->  
            ignoreTasks.forEach {  
                if (task.name.containsIgnoreCase(it)) {  
                    task.enabled = false  
                }  
            }  
        }  
        applicationVariants.configureEach { variant ->  
            variant.getPackageApplicationProvider().configure {  
                it.outputDirectory = new File(rootProject.buildDir.absolutePath + "/skins/${variant.buildType.name}")  
            }  
            variant.outputs.configureEach {  
                outputFileName = "${skinName}.skin"  
            }  
      }  
}

执行app的assembleReslease或者assembleDebug会在工程根目录的build/skin中的release或者debug文件夹中生成生产皮肤包,皮肤包的后缀以.skin结尾。

最后将皮肤包放置在指定的资源目录(放置方式可以是系统集成、可以放置在asset文件夹、也可以网络动态下发,根据自身应用实际需要的使用场景进行放置)。然后应用在所需的场景下触发SDK加载即可。

关于作者&Git链接

RangerSkin这个名字,其实源自我的英文名字"Ranger Leo"。作为摸爬滚打了10年的老程序员,我在行业领域经历了不少风风雨雨,也积累了许多宝贵的经验。

这么多年来,我遇到了无数的问题和挑战。有些问题本身就没有完美的解决方案,有些则在Kotlin普及和AGP7之后,开源方案出现了断档,而我却乐于寻找和实践最佳解决方案。因此,我自研了进程通信、进程消息总线、换肤等项目,希望能为行业带来一些新的思考和解决方案。

RangerSkin不仅仅是一个项目名称,它更代表了我对技术的热情和追求。我希望通过这个项目,能够为开发者们提供一个灵活、稳定且易于使用的界面定制方案,满足他们对性能和稳定性的需求。 愚人浅见,望各路英豪不吝赐教。

此外,特别声明,RangerSkin本次释放为lite版。和完整版相比,仅功能存在阉割和内存性能上的微小差异。不影响正常使用,且作者会长期维护。创作不易,请尊重别人的劳动成果,共同营造良好环境。如需完整版请联系作者。

详细接入和演示Github链接:RangerSkin

相关推荐
用户2018792831671 小时前
AMS和app通信的小秘密
android
用户2018792831671 小时前
ThreadPoolExecutor之市场雇工的故事
android
诺诺Okami1 小时前
Android Framework-Launcher-InvariantDeviceProfile
android
Antonio9152 小时前
【音视频】Android NDK 与.so库适配
android·音视频
sun00770011 小时前
android ndk编译valgrind
android
AI视觉网奇12 小时前
android studio 断点无效
android·ide·android studio
jiaxi的天空12 小时前
android studio gradle 访问不了
android·ide·android studio
No Silver Bullet13 小时前
android组包时会把从maven私服获取的包下载到本地吗
android
catchadmin13 小时前
PHP serialize 序列化完全指南
android·开发语言·php
tangweiguo0305198715 小时前
Kable使用指南:Android BLE开发的现代化解决方案
android·kotlin