因为接入方需要提供 .jar 形式的依赖包进行接入,资源文件要分开提供。即不能通过原生R.xxx的方式获取资源,因为 R.xxx 是最后编译生成,在库内部使用 R.xxx 的值并不能匹配到最后的 编译生成的 id。

我们在 Android Library 里想要获取资源文件需要通过调用 getResources().getIdentifier("res_name", "res_type", "package_name") 而不是 APP 层面的 getResoureces().getColor(id) 的形式。

但这样的代码会导致两个问题:

  1. 需要维护一份”res_name”的列表来与资源文件里的 id 达成映射关系
  2. 由于是硬编码的字符串,在资源文件的 id 有改动时,IDE 并不能发现变化,可能导致映射无效,直到程序崩溃才发现问题

解决方案

有网友提供了一个方案来解决上面的问题,但是用 Python 脚本手动生成一个映射表的方式并不优雅,除了需要额外的配置外还需手动生成。

那么有没有一个优雅简洁的方案呢?

通过参考 Butter Knife 源码,写了一个在 Gradle 编译时自动生成 R2.java 即 id 映射表的 Gradle 插件,与上面网友的方案相比会稍微优雅一点。

使用方法为

  1. 把下面的代码添加至buildscript

    1
    2
    3
    4
    5
    6
    7
    8
    buildscript {
    repositories {
    maven { url 'https://jitpack.io' }
    }
    dependencies {
    classpath 'com.github.nichbar:r2generator:1.0.3'
    }
    }
  2. 在要应用的 Library 里添加:

    1
    apply plugin: 'r2generator-plugin'

点一下Gradle Sync然后就可以直接使用 R2.xxx 了。

基本原理

插件的原理很简单,就是在 Gradle 编译期间对原 Gradle 生成的 R.java 文件进行读取,然后再把读到的 R.java 信息略加修改生成并写到 R2.java 里

源码及更多细节可见 r2generator