使用Room + Kotlin时出现“无法合并dex”错误

我不是英语的母语用户。 请原谅我的拼写和语法错误。

我尝试用Kotlin实现Android架构的Room数据库接口。 在将Room引入到我的项目之后,应用程序发生构建错误。

Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. > com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex 

我在终端运行gradlew并得到以下错误信息:

 // from gradlew org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:63) at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88) at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248) at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336) at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328) at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197) at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:124) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:80) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:105) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:99) at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:625) at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:580) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:99) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex at com.android.builder.dexing.DxDexArchiveMerger.mergeMonoDex(DxDexArchiveMerger.java:178) at com.android.builder.dexing.DxDexArchiveMerger.mergeDexArchives(DxDexArchiveMerger.java:119) at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:97) at com.android.build.gradle.internal.transforms.ExternalLibsMergerTransform.transform(ExternalLibsMergerTransform.kt:121) at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:222) at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:218) at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102) at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:213) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73) at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$IncrementalTaskAction.doExecute(DefaultTaskClassInfoStore.java:173) at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134) at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:121) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:122) at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336) at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328) at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197) at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:111) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92) ... 27 more Caused by: java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex at com.android.builder.dexing.DxDexArchiveMerger.lambda$mergeMonoDex$0(DxDexArchiveMerger.java:172) Caused by: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex Caused by: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:72) at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:36) Caused by: com.android.dex.DexException: Multiple dex files define Landroid/arch/persistence/room/SharedSQLiteStatement; at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:661) at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:616) at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:598) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171) at com.android.dx.merge.DexMerger.merge(DexMerger.java:198) at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:61) ... 1 more 

我试过这个问题的解决方案: 无法合并dex 。 他们不适合我


build.gradle文件和Room数据库文件列表如下:

 // build.gradle apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { // version code def verMajor = 0 def verMinor = 0 def verPatch = 1 def verHotfix = '' // compile wtih sdk 26 (Android - O) compileSdkVersion 26 buildToolsVersion "26.0.1" defaultConfig { applicationId "com.tomazwang.project.kotlinandroid" minSdkVersion 17 targetSdkVersion 26 versionCode verMajor * 10000 + verMinor * 100 + verPatch versionName "$verMajor.$verMinor.$verPatch$verHotfix" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // support library String supportVersion = '26.1.0' implementation "com.android.support:appcompat-v7:$supportVersion" implementation "com.android.support:design:$supportVersion" implementation "com.android.support.constraint:constraint-layout:1.1.0-beta1" // Anko String anko_version = '0.10.1' implementation "org.jetbrains.anko:anko-commons:$anko_version" implementation "org.jetbrains.anko:anko-sqlite:$anko_version" // RxJava String rxJavaVersion = '2.1.4' implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" String rxAndroidVersion = '2.0.1' implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion" // Android architecture String anArchVersion = '1.0.0-alpha9-1' implementation "android.arch.persistence.room:runtime:$anArchVersion" implementation "android.arch.persistence.room:rxjava2:$anArchVersion" annotationProcessor "android.arch.persistence.room:compiler:$anArchVersion" // Stetho String stethoVersion = '1.5.0' implementation "com.facebook.stetho:stetho:$stethoVersion" testImplementation 'junit:junit:4.12' androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', { exclude group: 'com.android.support', module: 'support-annotations' }) implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" } 
 // AppDatabase.kt @Database( entities = arrayOf(Todo::class), version = DbContract.VERSION ) abstract class AppDatabase : RoomDatabase(){ abstract fun todoDao(): TodoDao companion object { fun createInMemoryDatabase(context: Context): AppDatabase = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build() fun createPersistentDatabase(context: Context): AppDatabase = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, DbContract.DB_NAME).build() } } 
 // TodoDao.kt @Dao abstract class TodoDao { fun createTodo(name: String, description: String = "") { insertOrUpdate(Todo( id = 0, name = name, position = lastPosition() + 1, description = description )) } @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun insertOrUpdate(todo: Todo) @Query("SELECT * FROM ${TableTodo.TABLE_NAME} WHERE ${TableTodo.COL_ID} = :id") abstract fun getTodo(id: Long): Maybe<Todo> @Query("SELECT * FROM ${TableTodo.TABLE_NAME} ORDER BY ${TableTodo.COL_POSITION}") abstract fun getTodos(): Flowable<List<Todo>> } 
 // Todo.kt @Entity( tableName = TableTodo.TABLE_NAME ) data class Todo( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = TableTodo.COL_ID) val id: Long, @ColumnInfo(name = TableTodo.COL_NAME) val name: String = "", @ColumnInfo(name = TableTodo.COL_POSITION) val position: Long = 0, @ColumnInfo(name = TableTodo.COL_DESCRIPTION) val description: String = "", @ColumnInfo(name = TableTodo.COL_CHECKED) val checked:Boolean = false ) 

这是问题来源:

 Multiple dex files define Landroid/arch/persistence/room/SharedSQLiteStatement; 

重新检查依赖关系,可能你有一个Room包括多个时间。

将String anArchVersion ='1.0.0-alpha9-1'替换为String anArchVersion ='1.0.0-rc1'。