gpt4 book ai didi

安卓java.lang.NoClassDefFoundError : R$string

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:03 24 4
gpt4 key购买 nike

每当我运行单元测试时,当它尝试从自定义 config.xml 文件中检索字符串值时,我都会收到此错误。

背景:

该项目本身是一个库 apk 项目,它使用并引用了另一个库 APK 项目。

当项目本身尝试启动一个新对象时,会发生错误,该新对象是引用库 apk 项目中包含的父类(super class)的子类。

问题在下面有更多解释

因错误而失败的特定代码行是下面定义的静态变量:

  protected static final String ANDROID_CONFIG_ID =  LibraryApplication.getApplication().getString(R.string.api_checkout_config_id_override);

失败并出现以下错误:

java.lang.NoClassDefFoundError: com/jon/commonlib/R$string

如果您想知道的话,commonLib 就是引用的库 apk。

这是我的单元测试

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, manifest=Config.NONE)
public class TestSearchShows {

@Test
public void testSearchJsonFile(){
EventsTestHelper testHelper = new EventsTestHelper(RuntimeEnvironment.application);

try {
ShowsList showList = testHelper.getShowList(new SearchEvent());

if(showList.getShows().size() < 0){
Assert.fail("show list is empty");
}

} catch (IOException e) {
e.printStackTrace();
Assert.fail(e.toString());
}
}


}

EventsTestHelper 是名为 NetworkHelper 的父类(super class)的子类,如下所示:

public abstract class NetworkHelper<T, P, S> implements NetworkConstants {

protected static final String ANDROID_CONFIG_ID = LibraryApplication.getApplication().getString(R.string.api_checkout_config_id_override);

//other stuff ....

}

我使用最新的 robolectric 3.0 版来运行我的单元测试。

如果我要实时运行代码并调用和启动子类,它工作得很好,没有崩溃

编辑:下面是我的构建 gradle 文件的 fragment

apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
apply plugin: 'crashlytics'


buildscript {
repositories {
jcenter()
mavenCentral()
maven { url 'http://download.crashlytics.com/maven' }
maven { url 'http://www.testfairy.com/maven' }

}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'
classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+'
classpath 'com.testfairy.plugins.gradle:testfairy:1.+'

}
}

repositories {
mavenCentral()
maven { url 'http://download.crashlytics.com/maven' }
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
flatDir {
dirs 'libs'
}
}

android {
compileSdkVersion 19
buildToolsVersion "22.0.1"
def package_namespace = "com.jonney.moduleApp"

defaultConfig {
minSdkVersion 14
testApplicationId "com.jonney.moduleApp"
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
productFlavors {
//testing {
//}
local {
}
mock {
}
qa {
}
//qa4 {
//}
production {
}
}

sourceSets {



local {
res.srcDir 'build-config/local/res'
}
testing {
res.srcDir 'build-config/testing/res'
}
mock {
res.srcDir 'build-config/mock/res'
}
qa {
res.srcDir 'build-config/qa/res'
}
qa4 {
res.srcDir 'build-config/qa4/res'
}
staging {
res.srcDir 'build-config/staging/res'
test.java.srcDirs += 'src/main/java'
}
production {
res.srcDir 'build-config/production/res'
test.java.srcDirs += 'src/main/java'
test.java.srcDirs += "build/generated/source/r/production"
test.java.srcDirs += "build/generated/source/buildConfig/production"
}

}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.1.+'
compile 'com.google.code.gson:gson:2.3'
testCompile('org.robolectric:robolectric:3.0') {
exclude group: 'commons-logging', module: 'commons-logging'
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
}
compile 'com.fasterxml.jackson:jackson-parent:2.5'
compile 'com.squareup:otto:1.3.6'
compile 'com.jakewharton:butterknife:6.1.0'
compile 'com.sothree.slidinguppanel:library:3.0.0'
compile 'com.crashlytics.android:crashlytics:1.+'
compile 'com.mcxiaoke.volley:library-aar:1.0.0'
compile "joda-time:joda-time:2.4"
testCompile('junit:junit:4.12') {
exclude module: 'hamcrest'
exclude module: 'hamcrest-core'
}
testCompile 'org.hamcrest:hamcrest-all:1.3'
compile 'com.sothree.slidinguppanel:library:3.0.0'
compile 'com.squareup:otto:1.3.6'
compile 'com.squareup.okhttp:okhttp:2.3.0'
testCompile 'org.apache.maven:maven-ant-tasks:2.1.3'

compile 'com.google.android.gms:play-services:7.0.0'

compile 'com.android.support:multidex:1.0.0'

compile(name: 'commonLib 1.0 1', ext: 'aar')
testCompile(name: 'commonLib-1.0 1', ext: 'aar')
}

编辑:我还尝试手动创建一个任务,为每个依赖项复制 r 类。

    afterEvaluate { project ->
android.libraryVariants.each { variant ->
// workaround for missing R class for aar dependencies
def copyTaskName = "copy${variant.name.capitalize()}AppCompat"
def copyTaskNameTwo = "copy${variant.name.capitalize()}commonlib"
task(copyTaskName, type:Copy) {
dependsOn "process${variant.name.capitalize()}Resources"
from { "build/generated/source/r/${variant.dirName}/$package_namespace_path" }
into { "build/generated/source/r/${variant.dirName}/com/jon/commonlib" }
// into { "src/test/java/android/support/v7/appcompat" }
include 'R.java'
filter { line -> line.contains("package ${package_namespace};") ? 'package android.support.v7.appcompat;' : line }
outputs.upToDateWhen { false }
}
task(copyTaskNameTwo, type:Copy) {
dependsOn "process${variant.name.capitalize()}Resources"
from { "build/generated/source/r/${variant.dirName}/$package_namespace_path" }
into { "build/generated/source/r/${variant.dirName}/android/support/v7/appcompat" }
// into { "src/test/java/android/support/v7/appcompat" }
include 'R.java'
filter { line -> line.contains("package ${package_namespace};") ? 'package com.jon.commonlib;' : line }
outputs.upToDateWhen { false }
}
System.out.println("adding ${copyTaskName} build/generated/source/r/${variant.dirName}/$package_namespace_path ")
println("basename = ${variant.baseName}")
println("directory name = ${variant.dirName}")
tasks.getByName("compile${variant.name.capitalize()}UnitTestJava") dependsOn copyTaskName
}
}

亲切的问候

强尼

最佳答案

The project itself is a library apk project that uses and references another library APK project.

对于此类项目,存在一个已知问题 https://github.com/robolectric/robolectric/issues/1796但您可以解决它。

基本问题是库项目的 android/gradle 行为与应用程序项目不同。它只是忽略从 aar 依赖项生成 R 类。

要解决此问题,您可以提供自己的 R 类,该类已包含所有依赖项 R 值。这里有一个 appcompat 依赖的例子

afterEvaluate { project ->
android.libraryVariants.each { variant ->
// one line for each aar dependency
tasks.getByName("assemble${variant.name.capitalize()}").dependsOn copyAppcompat
}
}

// copy it for each aar dependency and adjust it to your needs
task copyAppcompat(type: Copy) {

// replace the base package with yours (all after /r/debug/) which contains your R.class
from 'build/generated/source/r/debug/com/example/core'.replace("/", File.separator)

// replace the library packages with yours (all after /test/java/) with your aar dependency base package
into 'src/test/java/android/support/v7/appcompat'.replace("/", File.separator)

// also replace the package declaration or you will get compile errors
filter { line -> line.contains('package com.example.core;') ? 'package android.support.v7.appcompat;' : line }
include 'R.java'
}

可以在 https://github.com/nenick/AndroidStudioAndRobolectric/tree/library-with-aar 找到包含您的设置的示例项目

关于安卓java.lang.NoClassDefFoundError : R$string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32099956/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com