这个文章的标题容易让人引起误解,不是不能用,而是有使用场景的,这篇文章会详细分析一下:
一般情况下android工程中R.class中的资源常量定义如下:
1 |
public static final int main=0x7f030004; |
但是, 在ADT 14 版本且如果是 library 工程,这些常量在R.class里面就不再是final 了
1 |
public static int main=0x7f030004; |
换句话说这些常量在 library 工程不是 final 的了,原因很简单,当多个 library工程合并,这些字段的实际值可能会冲突(android中的资源id是必须唯一的)。在ADT 14之前,所有的字段都是final的,所以所有的 library 的resources, java 代码必须和主工程一起重新编译,这样效率就很低,这个让编译很慢,同时这样也让很多没有 source code的 library工程无法使用,限制了 library工程的使用范围。
这些R.class里面的字段不再是final 的目的是让这些library jars只编译一次,并且可以在其它的工程中可以直接复用,这样的话就允许 library 工程编译自己的二进制版本(不包含源码),这样编译快了很多。
但是这个对library的源码会有一个影响,以下格式的代码将不会编译:
1 2 3 4 5 6 7 8 9 10 11 12 |
int id = view.getId(); switch (id) { case R.id.button1: action1(); break; case R.id.button2: action2(); break; case R.id.button3: action3(); break; } |
原因是 swich 语句需要所有的 case 使用(例如:R.id.button1)在编译期间必须是常量(这样值就可以直接复制到.class文件中)。
解决这个问题很简单,可以把 switch 语句改为 if-else 语句。幸运的是这个在eclipse中非常方便,把鼠标放在switch 关键字上按键盘的 Ctrl-1(或者在mac上面Cmd-1)
这样switch就会转换成如下格式:
1 2 3 4 5 6 7 8 |
int id = view.getId(); if (id == R.id.button1) { action1(); } else if (id == R.id.button2) { action2(); } else if (id == R.id.button3) { action3(); } |
P.S. 如果的你的swich是这样的
1 |
switch (view.getId()) { |
这样会让最终生成的if-else语句执行效率不高,因为会在每次if检查时调用一次view.getId(),所以在转换之前需要把view.getId提取出来