简介
一款安卓原生应用换肤框架。基于安卓View绘制原理和主流LayoutInflaterCompat.setFactory2 方案,使用kotlin协程+flow进行封装,对View属性 进行AOP定制 。
RangerSkin
可运用于手机、车机等全场景安卓生态换肤方案的现。历经百天内存性能压测,几乎不存在内存和CPU额外负载消耗。愿为行业内现行换肤方案的最佳实践。
优势
- 皮肤包可工程独立。出色的项目安全和稳定性,对原工程侵入小,几乎没有改造风险
- 采用增量订制的方式,项目适配改动工作小,支持项目分期适配
- API极简,功能强大,涵盖几乎所有原生换肤定制场景
- 支持minifyEnabled和shrinkResources
- 性能的极致要求,充分验证,开发者无需关注内存泄漏等性能风险
方案对比
想要了解换肤方案和主流实践的同学请移步对 Android 应用换肤方案的总结,文章已经进行较为深度的对比总结,且文中提过的框架早已不再维护,作者认为没有可比性,在此不再进行赘述。前期设计和研发SDK借鉴了文章中提到的主要的细节的点尤其是各方案的不足,并在
RangerSkin
中进行补充完善。在此对文章作者开发者如是说以及相关方案框架的作者表示感谢。
接入流程
- 集成
SDK版本要求和注意事项: 安卓21及以上,Kotlin1.4及以上版本(项目中如果不存在Kotlin可以不用关注)。
kotlin
repositories {
mavenCentral()
}
kotlin
dependencies {
implementation "io.github.rangerleoio.rangerskin:skin-lite:1.0.0" //请及时同步最新Release SDK版本
}
- 适配流程
流程图
属性支持列表
background | src | textColor | textSize |
---|---|---|---|
text | hint | textColorHint | textCursorDrawable |
tint | foregroundTint | backgroundTint | style和?attr |
- 制作皮肤包
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