最近研究android 组件化过程中 遇到了一个问题 给一个library 中的 button 添加点击监听时 使用switch-case访问button id 飘红报错
提示是
Resource IDs cannot be used in a switch statement in Android library modules less.
Validates using resource IDs in a switch statement in Android library module. Resource IDs are non final in the library projects since SDK tools r14, means that the library code cannot treat these IDs as constants.
这段话告诉我 这个id 在library module 的 switch 语句中使用 由于sdk r14版本的问题,资源id在库项目中是非final的,这意味着库代码不能将这些id视为常量。意思也就是说 switch - case 无法引用变量作为资源id 的指向 他所需要的是常量 还有一个关键是 sdk r14的原因 下面说到
当我取消以来 library 转换成 application 时 又可以了 也就是说这种情况并不是我书写问题 而是和module 的 类型有关 接着上面分析 查看一下R库的id 看一下两者的区别
图例1 (library module 的id格式)
图例2 (application module 的 id 格式)
对比发现 library 是static 形式的int (静态变量) 而 在application中 是 static final 形式的 int(静态常量) 联想到上面的提示 就可以发现问题所在 在 library module 中 switch - case 无法引用变量作为资源id 的指向 这里是根源 再来看看 sdk r14 (android sdk 官网地址有兴趣可以了解一下 http://tools.android.com/tips/non-constant-fields)
Non-constant Fields in Case Labels
In a regular Android project, constants in the resource R class are declared like this:
public static final int main=0x7f030004;
However, as of ADT 14, in a library project, they will be declared like this:
public static int main=0x7f030004;
In other words, the constants are not final in a library project. The reason for this is simple: When multiple library projects are combined, the actual values of the fields (which must be unique) could collide. Before ADT 14, all fields were final, so as a result, all libraries had to have all their resources and associated Java code recompiled along with the main project whenever they were used. This was bad for performance, since it made builds very slow. It also prevented distributing library projects that didn't include the source code, limiting the usage scope of library projects.
这个不恒定字段标签 提示我们 ADT 14版本开始 application module 的 R文件声明 是这样的
public static final int main=0x7f030004;
而 library module 的R文件声明 将会是这样的
public static int main=0x7f030004;
在ADT 14 版本以前 无论是application module 还是library module都是 public static final int main=0x7f030004; 这种格式 这就导致了 资源重名问题 导致引用错误 细心的朋友可能发现了 我的两张图例中 都存在list_bt_1 这个字段名 只不过是一个是static int 另一个是 static final int 两种不同形式而已 这也就是官方提到的In other words... 这一段话的解释 了android 优化这一设计问题的原因
下面说一下解决方法
方式一 代码稍多
findViewById(R.id.list_bt_1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
方式二
@Override
public void onClick(View view) {
/**
* switch - case 无法引用变量作为资源id 的指向
*/
int i = view.getId();
if (i == R.id.list_bt_1) {
Toast.makeText(this, "点击了1", Toast.LENGTH_SHORT).show();
}
}
当然这是一些原生的方式 有关注解之类的 也是可以的 这一块留给有需要的人自行研究 这里我就不说了 好了 本文完结 若有疑问 欢迎留言或私信