我在一台设备上运行espresso测试时遇到问题 - 我收到以下错误:
W/dalvikvm(10180): Class resolved by unexpected DEX: Lorg/ligi/passandroid/App;(0x43876120):0x660f9000 ref [Lorg/ligi/passandroid/AppComponent;] Lorg/ligi/passandroid/AppComponent;(0x43876120):0x64e2f000
W/dalvikvm(10180): (Lorg/ligi/passandroid/App; had used a different Lorg/ligi/passandroid/AppComponent; during pre-verification)
D/AndroidRuntime(10180): Shutting down VM
W/dalvikvm(10180): threadid=1: thread exiting with uncaught exception (group=0x433101a0)
E/MonitoringInstrumentation(10180): Exception encountered by: Thread[main,5,main]. Dumping thread state to outputs and pining for the fjords.
E/MonitoringInstrumentation(10180): java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
E/MonitoringInstrumentation(10180): at org.ligi.passandroid.App.onCreate(App.java:26)
E/MonitoringInstrumentation(10180): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
E/MonitoringInstrumentation(10180): at android.support.test.runner.MonitoringInstrumentation.callApplicationOnCreate(MonitoringInstrumentation.java:323)
E/MonitoringInstrumentation(10180): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4749)
E/MonitoringInstrumentation(10180): at android.app.ActivityThread.access$1600(ActivityThread.java:172)
E/MonitoringInstrumentation(10180): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
E/MonitoringInstrumentation(10180): at android.os.Handler.dispatchMessage(Handler.java:102)
E/MonitoringInstrumentation(10180): at android.os.Looper.loop(Looper.java:146)
E/MonitoringInstrumentation(10180): at android.app.ActivityThread.main(ActivityThread.java:5653)
E/MonitoringInstrumentation(10180): at java.lang.reflect.Method.invokeNative(Native Method)
E/MonitoringInstrumentation(10180): at java.lang.reflect.Method.invoke(Method.java:515)
E/MonitoringInstrumentation(10180): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
E/MonitoringInstrumentation(10180): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
E/MonitoringInstrumentation(10180): at dalvik.system.NativeStart.main(Native Method)
我排除了所有内容,因此应该没有重复的库 - 这里是我对test-app的依赖:
_withMapsWithAnalyticsForPlayDebugAndroidTestApk - ## Internal use, do not manually configure ##
+--- com.github.ligi:trulesk:0.19
| +--- com.android.support.test.espresso:espresso-intents:2.2.2
| | \--- com.android.support.test.espresso:espresso-core:2.2.2
| | +--- com.squareup:javawriter:2.1.1
| | +--- com.android.support.test:rules:0.5
| | | \--- com.android.support.test:runner:0.5
| | | +--- junit:junit:4.12
| | | | \--- org.hamcrest:hamcrest-core:1.3
| | | \--- com.android.support.test:exposed-instrumentation-api-publish:0.5
| | +--- com.android.support.test:runner:0.5 (*)
| | +--- org.hamcrest:hamcrest-library:1.3
| | | \--- org.hamcrest:hamcrest-core:1.3
| | +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2
| | \--- org.hamcrest:hamcrest-integration:1.3
| | \--- org.hamcrest:hamcrest-library:1.3 (*)
| +--- com.jraska:falcon-spoon-compat:1.0.3
| | +--- com.jraska:falcon:1.0.3
| | \--- com.squareup.spoon:spoon-client:1.6.2
| \--- com.linkedin.testbutler:test-butler-library:1.1.0
+--- com.squareup.assertj:assertj-android:1.1.1
| \--- org.assertj:assertj-core:1.7.1
+--- org.mockito:mockito-core:2.7.22
| +--- net.bytebuddy:byte-buddy:1.6.11
| +--- net.bytebuddy:byte-buddy-agent:1.6.11
| \--- org.objenesis:objenesis:2.5
\--- com.linkedin.dexmaker:dexmaker-mockito:2.2.0
+--- com.linkedin.dexmaker:dexmaker:2.2.0
| \--- com.jakewharton.android.repackaged:dalvik-dx:7.1.0_r7
| \--- com.jakewharton.android.repackaged:libcore-dex:7.1.0_r7
\--- org.mockito:mockito-core:2.2.29 -> 2.7.22 (*)
AppComponent是一个匕首组件:
package org.ligi.passandroid
import dagger.Component
import org.ligi.passandroid.model.PassStore
import org.ligi.passandroid.model.Settings
import org.ligi.passandroid.ui.*
import org.ligi.passandroid.ui.edit.FieldsEditFragment
import org.ligi.passandroid.ui.quirk_fix.USAirwaysLoadActivity
import javax.inject.Singleton
@Singleton
@Component(modules = arrayOf(AppModule::class, TrackerModule::class))
interface AppComponent {
fun inject(passViewActivityBase: PassViewActivityBase)
fun inject(passListActivity: PassListActivity)
fun inject(passEditActivity: PassEditActivity)
fun inject(passAdapter: PassAdapter)
fun inject(passImportActivity: PassImportActivity)
fun inject(passMenuOptions: PassMenuOptions)
fun inject(searchPassesIntentService: SearchPassesIntentService)
fun inject(usAirwaysLoadActivity: USAirwaysLoadActivity)
fun inject(passAndroidActivity: PassAndroidActivity)
fun inject(passListFragment: PassListFragment)
fun inject(passNavigationView: PassNavigationView)
fun inject(touchImageActivity: TouchImageActivity)
fun inject(fieldsEditFragment: FieldsEditFragment)
fun passStore(): PassStore
fun tracker(): Tracker
fun settings(): Settings
}
logcat中有一些奇怪的输出:
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Annotation;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/ClassData$Field;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/ClassData$Method;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/ClassData;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/ClassDef;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Code$CatchHandler;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Code$Try;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Code;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$1;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$ClassDefIterable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$ClassDefIterator;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$FieldIdTable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$MethodIdTable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$ProtoIdTable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$StringTable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$TypeIndexToDescriptorIndexTable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex$TypeIndexToDescriptorTable;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Dex;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/DexFormat;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/EncodedValue;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/EncodedValueCodec;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/EncodedValueReader;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/FieldId;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Leb128;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/MethodId;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/Mutf8;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/ProtoId;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/SizeOf;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/TableOfContents$Section;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/TableOfContents;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/TypeList;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/util/ByteInput;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/util/ByteOutput;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/util/ExceptionWithContext;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/util/FileUtils;' has an earlier definition; blocking out
D/dalvikvm( 4357): DexOpt: 'Lcom/android/dex/util/Unsigned;' has an earlier definition; blocking out
我坚持了2天,现在只是忽略了设备。不知道如何从这里开始。其他设备运行正常,手动测试时应用程序可在设备上运行。
编辑 - 按要求的App和TestApp:
package org.ligi.passandroid;
import android.app.Application;
import android.support.annotation.VisibleForTesting;
import android.support.v7.app.AppCompatDelegate;
import com.jakewharton.threetenabp.AndroidThreeTen;
import com.squareup.leakcanary.LeakCanary;
import org.ligi.tracedroid.TraceDroid;
import org.ligi.tracedroid.logging.Log;
public class App extends Application {
private static AppComponent component;
@Override
public void onCreate() {
super.onCreate();
component = createComponent();
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
installLeakCanary();
AndroidThreeTen.init(this);
initTraceDroid();
AppCompatDelegate.setDefaultNightMode(component.settings().getNightMode());
}
public void installLeakCanary() {
LeakCanary.install(this);
}
public AppComponent createComponent() {
return DaggerAppComponent.builder().appModule(new AppModule(this)).trackerModule(new TrackerModule(this)).build();
}
private void initTraceDroid() {
TraceDroid.init(this);
Log.setTAG("PassAndroid");
}
public static AppComponent component() {
return component;
}
@VisibleForTesting
public static void setComponent(AppComponent newComponent) {
component = newComponent;
}
}
和TestApp:
public class TestApp extends App {
@Override
public AppComponent createComponent() {
return DaggerTestComponent.builder().testModule(new TestModule()).build();
}
public static TestComponent component() {
return (TestComponent) App.component();
}
@Override
public void installLeakCanary() {
}
public static PassStore getPassStore() {
return component().passStore();
}
public static void reset() {
setComponent(DaggerTestComponent.builder().testModule(new TestModule()).build());
}
}