Android Studio引入Library后运行报"Resources$NotFoundException"的解决办法(原)
2017-02-27 14:25
851 查看
【前提条件】
Eclipse导出的Library工程,其中的src目录被编译为jar,然后将此Library合入AndroidStudio中,编译(build)可以通过,但是运行(run)报错,报错信息:
android.content.res.Resources$NotFoundException: Resource ID #0x7f030003
【主要特征】
1、Library和宿主工程均编译通过,但是运行时出现crash;
2、Library的res/value目录下存在public.xml和ids.xml文件;
3、在Eclipse工程下使用该Library运行通过,AndroidStudio工程使用该Library出现crash;
4、核实Eclipse工程发现其gen目录下生成的R文件中的ID和res/value目录下public.xml中的ID是相同的,但是AndroidStudio的app\build\generated\source\r\debug\目录下的R文件与public.xml文件中同名的资源项ID不同;
【原因分析】
1、Android的资源ID在编译时才可以确定下来,也就是说,每次编译的R文件中ID都可能是不一样的,这就给Library工程的打包造成了困扰,因为Library一旦打包完成,其src中的代码就锁定了,但是R文件却会在每次编译过程中更换,为了解决此问题,打包Library时,开发者往往会选择使用固定资源ID的形式,将Library中的资源ID固定下来,这样Library中打包的java就可以顺利找到R.java中的资源了。
2、以上的"固定资源ID"的方法,会在Library工程的"res\values"目录下生成ids.xml和public.xml两个文件,其内容就是让AAPT在打包该package资源时,使用public.xml中规定的资源ID;
3、Eclipse在引用该Library工程时,就会按照2中描述的过程生成固定的R.java文件,从而让jar中的src可以顺利找到自己的资源包;
4、但是当该Library被AndroidStudio工程编译时(gradle版本大于1.3.0时)AndroidStudio就会忽略public.xml文件,重新为每个资源生成ID,如此,Library中的src文件就会找不到Library中的资源ID,导致报错;
【解决思路】
在AndroidStudio的工程的build.gradle文件中对gradle进行配置,让其在利用AAPT生成资源ID时扫描public.xml文件,使用固定的资源ID。
【具体步骤】
1、在AndroidStudio的Library工程目录下build.gradle同级目录添加文件"public-xml.gradle",内容如下:
2、在Library的build.gradle文件中添加如下内容:
3、在AndroidStudio的app主工程的build.gradle同级目录下添加文件"public-xml.gradle",其内容如下:
这个脚本与Library中脚本的唯一区别就是applicationVariants和libraryVariants。
4、在app的build.gradle文件中添加如下内容:
Eclipse导出的Library工程,其中的src目录被编译为jar,然后将此Library合入AndroidStudio中,编译(build)可以通过,但是运行(run)报错,报错信息:
android.content.res.Resources$NotFoundException: Resource ID #0x7f030003
【主要特征】
1、Library和宿主工程均编译通过,但是运行时出现crash;
2、Library的res/value目录下存在public.xml和ids.xml文件;
3、在Eclipse工程下使用该Library运行通过,AndroidStudio工程使用该Library出现crash;
4、核实Eclipse工程发现其gen目录下生成的R文件中的ID和res/value目录下public.xml中的ID是相同的,但是AndroidStudio的app\build\generated\source\r\debug\目录下的R文件与public.xml文件中同名的资源项ID不同;
【原因分析】
1、Android的资源ID在编译时才可以确定下来,也就是说,每次编译的R文件中ID都可能是不一样的,这就给Library工程的打包造成了困扰,因为Library一旦打包完成,其src中的代码就锁定了,但是R文件却会在每次编译过程中更换,为了解决此问题,打包Library时,开发者往往会选择使用固定资源ID的形式,将Library中的资源ID固定下来,这样Library中打包的java就可以顺利找到R.java中的资源了。
2、以上的"固定资源ID"的方法,会在Library工程的"res\values"目录下生成ids.xml和public.xml两个文件,其内容就是让AAPT在打包该package资源时,使用public.xml中规定的资源ID;
3、Eclipse在引用该Library工程时,就会按照2中描述的过程生成固定的R.java文件,从而让jar中的src可以顺利找到自己的资源包;
4、但是当该Library被AndroidStudio工程编译时(gradle版本大于1.3.0时)AndroidStudio就会忽略public.xml文件,重新为每个资源生成ID,如此,Library中的src文件就会找不到Library中的资源ID,导致报错;
【解决思路】
在AndroidStudio的工程的build.gradle文件中对gradle进行配置,让其在利用AAPT生成资源ID时扫描public.xml文件,使用固定的资源ID。
【具体步骤】
1、在AndroidStudio的Library工程目录下build.gradle同级目录添加文件"public-xml.gradle",内容如下:
afterEvaluate { for (variant in android.libraryVariants) { def scope = variant.getVariantData().getScope() String mergeTaskName = scope.getMergeResourcesTask().name def mergeTask = tasks.getByName(mergeTaskName) mergeTask.doLast { copy { int i=0 from(android.sourceSets.main.res.srcDirs) { include 'values/public.xml' rename 'public.xml', (i++ == 0? "public.xml": "public_${i}.xml") } into(mergeTask.outputDir) } } } }
2、在Library的build.gradle文件中添加如下内容:
apply from: 'public-xml.gradle'
3、在AndroidStudio的app主工程的build.gradle同级目录下添加文件"public-xml.gradle",其内容如下:
afterEvaluate { for (variant in android.applicationVariants) { def scope = variant.getVariantData().getScope() String mergeTaskName = scope.getMergeResourcesTask().name def mergeTask = tasks.getByName(mergeTaskName) mergeTask.doLast { copy { int i=0 from(android.sourceSets.main.res.srcDirs) { include 'values/public.xml' rename 'public.xml', (i++ == 0? "public.xml": "public_${i}.xml") } into(mergeTask.outputDir) } } } }
这个脚本与Library中脚本的唯一区别就是applicationVariants和libraryVariants。
4、在app的build.gradle文件中添加如下内容:
apply from: 'public-xml.gradle'5、然后,重新rebuild工程即可(核实AndroidStudio生成的R文件与public.xml文件中ID一致)。
相关文章推荐
- Android报Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0 .解决办法
- android.content.res.Resources$NotFoundException: Resource ID解决办法
- android.content.res.Resources$NotFoundException: Resource ID解决办法
- Android报Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0 .解决办法
- android.content.res.Resources$NotFoundException错误的解决办法
- 关于android.content.res.Resources$NotFoundException: Resource is not a Drawable 问题的解决办法
- AndroidRuntime Caused by: android.content.res.Resources$NotFoundException: String resource I解决办法
- android.content.res.Resources$NotFoundException: String resource ID #0x6错误的解决办法
- hadoop 伪分布式系统命令行运行java类报Exception in thread "main" java.lang.ClassNotFoundException:解决办法
- Android中传送序列化对象出现的ClassNotFoundException解决办法
- android.os.BadParcelableException: ClassNotFoundException when unmarshalling:解决办法
- "library not found for - "解决办法
- 【解决】android.content.res.Resources$NotFoundException:String resource ID #0x86
- Resources$NotFoundException: Resource ID #0xffffffff的解决办法
- Andorid 引入Lib后 ClassNotFoundException解决办法
- "java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils"的解决办法
- android.os.BadParcelableException: ClassNotFoundException when unmarshalling:解决办法
- Rational Rose破解版 关于启动和关闭时都弹出"java.lang.ClassNotFoundException"的解决办法
- 新建JSP无法运行出现错误The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Pat解决办法