更多问答 >>
-
每日一问 很多时候我们说"Android16.6ms刷新一次屏幕" 正确吗?
2019-07-30 21:53 -
2019-08-01 21:44
-
每日一问 大家应该都有泛型在编译期会被擦除的概念,那么为什么我们在运行时还能读取到呢? 3/3
2019-08-04 19:44 -
每日一问 AppCompatTextView 与 TextView 1/3
2019-08-07 01:29 -
每日一问 匿名内部类访问的外部类局部变量为什么要用final 修饰,jdk8为啥不需要了? 2/3
2019-08-08 23:51 -
每日一问 听说过Handler中的IdleHandler吗?
2019-07-25 21:09 -
每日问答 Handler应该是大家再熟悉不过的类了,那么其中有个同步屏障机制,你了解多少呢?
2019-07-23 17:29 -
每日一问 Android 常见的制作圆角方案,有哪几种常见方式? 在Android P上什么兼容性问题
2019-07-21 16:48 -
每日一问 哪些 Context调用 startActivity 需要设置NEW_TASK,为什么?
2019-07-18 23:24 -
每日一问 如果项目要开始做编译速度优化,你会考虑从哪些地方入手?
2019-07-16 23:50
1.R文件是编译器生成的
2.lib module可以打成aar模式,注意这里的aar里面的jar是不包含R.class的,反而会是包含一个R.txt
为什么aar里面的jar不直接包含R.class呢?
这要设计R文件的id分配,默认是从0x7f + resId + 0001开始分配的
int anim mintegral_reward_activity_open 0x7f010001
int anim mintegral_reward_activity_stay 0x7f010002int attr alpha 0x7f040001
int attr coordinatorLayoutStyle 0x7f040002int id RelativeLayout1 0x7f0c0001
int id account 0x7f0c0002可见都是从0x7fXX0001开始分配的
那么假如有两个lib目录a和b,并且都有资源文件
肯定会有资源冲突的,因为每个lib都是从0x7fXX0001开始分配的
这里,as会自动处理冲突,会重定位资源id的开始区间,使得a的资源区间是从0x7fXX00XX开始
b的资源区间从另外一个开始,这样就不会有资源冲突了
处理冲突默认是按照字母顺序排序的,从a到z排序
public static final class layout {
public static final int abc_action_bar_title_item = 2131296256; // 7f090000public static final int abc_action_bar_up_container = 2131296257; // 7f090001
public static final int abc_action_menu_item_layout = 2131296258;
public static final int abc_action_menu_layout = 2131296259; public static final int abc_action_mode_bar = 2131296260; public static final int abc_action_mode_close_item_material = 2131296261; public static final int abc_activity_chooser_view = 2131296262; public static final int abc_activity_chooser_view_list_item = 2131296263; public static final int abc_alert_dialog_button_bar_material = 2131296264; public static final int abc_alert_dialog_material = 2131296265; public static final int abc_alert_dialog_title_material = 2131296266; public static final int abc_cascading_menu_item_layout = 2131296267; public static final int abc_dialog_title_material = 2131296268; public static final int abc_expanded_menu_layout = 2131296269; public static final int abc_list_menu_item_checkbox = 2131296270; public static final int abc_list_menu_item_icon = 2131296271; public static final int abc_list_menu_item_layout = 2131296272; public static final int abc_list_menu_item_radio = 2131296273; public static final int abc_popup_menu_header_item_layout = 2131296274; public static final int abc_popup_menu_item_layout = 2131296275; public static final int abc_screen_content_include = 2131296276; public static final int abc_screen_simple = 2131296277; public static final int abc_screen_simple_overlay_action_mode = 2131296278; public static final int abc_screen_toolbar = 2131296279; public static final int abc_search_dropdown_item_icons_2line = 2131296280; public static final int abc_search_view = 2131296281; public static final int abc_select_dialog_material = 2131296282; public static final int abc_tooltip = 2131296283; public static final int activity_lib = 2131296284; public static final int activity_main = 2131296285; public static final int notification_action = 2131296286; public static final int notification_action_tombstone = 2131296287; public static final int notification_template_custom_big = 2131296288; public static final int notification_template_icon_group = 2131296289; public static final int notification_template_part_chronometer = 2131296290; public static final int notification_template_part_time = 2131296291; public static final int select_dialog_item_material = 2131296292; public static final int select_dialog_multichoice_material = 2131296293; public static final int select_dialog_singlechoice_material = 2131296294; public static final int support_simple_spinner_dropdown_item = 2131296295; }是最后在编译apk时候,才能确定每个资源id的值
其实lib module 应该来说并没有R.java 文件,只是as的一个语法支持
在编译成apk时候会最终确定每个资源id的值
但最终每个lib库里面的R.class文件里面的值会是final类型的
在Android Studio 中将光标移动到switch关键字并按Alt+ Enter然后选择 将'switch'替换为'if'。
因为编译器的语法优化,会将R.id.axx替换成具体的210312344,而lib的资源id是还会变的,所以lib的资源id是不能用final声明的
在Java语法中,switch的参数必须是常量或者值,否则会报语法错误。所以我们一定会出现把 application 的 switch 移动到 module 的时候,报了语法错误,修改为 if-else 完美解决。
那为什么 application 下面的 R.java 都是静态常量,而 library 下面的 R.java 文件都是静态变量呢?
其实不难理解,我们在不同的 module 其实是可以设置一样的变量名称的,比如application下有layout_main.xml,在library里面也可以有这样的。如果你两个都是静态常量,怎么弄?在者,假设你在 application 编译 setContent(R.layout.layout_main),你也会在debug下发现它其实一个固定的值。所以合并的时候,你能知道我使用的是哪个么?
可以看看官方文档:https://developer.android.com/studio/write/add-resources.html
在Android-tips里有篇文章专门介绍了为什么把module的R.java 的字段设计为非final的,
module在编译时, 如果是final常量, 值会写死在生成的.class里, 无法更改, 然后会和别的模块,主模块冲突, 指向了错误的资源编号
这个改动可以参见:
http://tools.android.com/tips/non-constant-fields
其实很简单,如果lib中 R.java 文件里面的变量是 final 的,那么会有两个问题:
那到底有没有解决方案?转化成if-else就是解决方案?不还是不能用么。
解决方案, 光标指到switch,利用Alt+ Enter然后选择 将'switch'替换为'if'。