在平时开发的过程中对一些常量的判断,都是使用switch case
语句,因为switch case
比if else
的效率稍高。
但是也遇到了问题,就是在library
中使用时会报错:
public void testClick(View view) {
int id = view.getId();
switch (id) {
case R.id.bt_pull:
break;
case R.id.bt_push:
break;
}
}
我们来看一下错误提示:
意思就是在Android Library
的Module
中的switch
语句不能使用资源ID
.这是为什么呢? 我们都知道R
文件中都是常量啊,public static final
的,为什么不能用在switch
语句中,继续看下去:
Resource IDs are non final in th library projects since SDK tools r14, means that the library code cannot treat this IDs as constants.
说的灰常明白了,也就是说从14开始,library中的资源id
就不是final
类型的了,所以不是常量了。
在一个常规的Android
项目中,资源R
文件中的常量都是如下这样声明的:
public static final int main=0x7f030004;
然后,从ADT
14开始,在library
项目中,它们将被这样声明:
public static int main=0x7f030004;
也就是说在library
项目中这些常量不是final
的了。为什么这样做的原因也非常简单:当多个library
项目结合时,这些字段的实际值(必须唯一的值)可能会冲突。在ADT
14之前,所有的字段都是final
的,这样就导致了一个结果,就是所有的libraries
不论何时在被使用时都必须把他们所有的资源和相关的Java
代码都伴随着主项目一起重新编译。这样做是不合理的,因为它会导致编译非常慢。这也会阻碍一些没有源码的libraray
项目进行发布,极大的限制了library
项目的使用范围。
那些字段不再是final
的原因就是意味着library jars
可以被编译一次,然后在其他项目中直接被服用。也就是意味着允许发布二进制版本的library
项目(r15中开始支持),这让编译变的更快。
然而,这对library
的源码会有一个影响。类似下面这样的代码就将无法编译:
public void testClick(View view) {
int id = view.getId();
switch (id) {
case R.id.bt_pull:
break;
case R.id.bt_push:
break;
}
}
这是因为swtich
语句要求所有case
后的字段,例如R.di.bt_pull
在编译的时候都应该是常量(就像可以直接把值拷贝进.class
文件中)
当然针对这个问题的解决方法也很简单:就是把switch
语句改成if-else
语句。幸运的是,在eclise
中这是非常简单的。只需要在switch
的关键字上按Ctrl+1
(Mac
上是Cmd+1
)。(eclipse
都辣么方便了,Studio
更不用说了啊,直接按修复的快捷键就阔以了)。
上面的代码就将变成如下:
public void testClick(View view) {
int id = view.getId();
if (id == R.id.bt_pull) {
} else if (id == R.id.bt_push) {
}
}
这在UI代码和性能的影响通常是微不足道的 - -!。
- 邮箱 :charon.chui@gmail.com
- Good Luck!