Jetpack Composable没有静态方法的java.lang.NoSuchMethodError。

8

我正在创建一个用于基本对话框的Android库。目前,我只有一个名为basic-dialogs的模块以及app模块。我从app模块的Activity中调用basic-dialogs模块中的一个组合函数,当我尝试运行应用程序时,我不断收到有关No static method的异常错误消息。代码可能存在什么问题?

java.lang.NoSuchMethodError: No static method BasicDialog(Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V in class Lcom/<domain>/basic_dialogs/BasicDialogKt; or its super classes (declaration of 'com.<domain>.basic_dialogs.BasicDialogKt' appears in /data/app/~~DOqVbMGsnzDWFS7_YdNgtw==/com.<domain>.composedialogs-_5IuirMOFh5F8pL884Urnw==/base.apk!classes2.dex)

活动

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeDialogsTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    BasicDialog(onDismiss = {  }, onConfirmClick = {  }, title = "Test Dialog", confirmButtonText = "Open") {
                        Text("This is a test dialog.")
                    }
                }
            }
        }
    }
}

基础对话框 Composable

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun BasicDialog(
    title: String = "",
    confirmButtonText: String,
    onDismiss: () -> Unit,
    onConfirmClick: () -> Unit,
    content: @Composable () -> Unit
) {
    Surface(
        shape = MaterialTheme.shapes.medium,
        color = MaterialTheme.colors.surface,
        modifier = Modifier
            .padding(4.dp)
    ) {
        Dialog(
            onDismissRequest = onDismiss,
            properties = DialogProperties(
                dismissOnBackPress = true,
                dismissOnClickOutside = true,
                usePlatformDefaultWidth = false
            ),
        ) {
            if (title != "") {
                Text(title)
                Spacer(Modifier.padding(5.dp))
            }

            content()
            Spacer(Modifier.padding(5.dp))
            TextButton(onClick = onDismiss) {
                Text(text = stringResource(id = R.string.dialog_cancel), fontSize = 16.sp)
            }
            TextButton(onClick = { onConfirmClick() }) {
                Text(text = confirmButtonText, fontSize = 16.sp)
            }
        }
    }
}

Gradle 项目文件

buildscript {
    ext {
        compose_version = '1.1.0-beta01'
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.2.2' apply false
    id 'com.android.library' version '7.2.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.5.31' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

应用程序模块Gradle文件

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.<domain>.composedialogs"
        minSdk 27
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary true
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.3.1'
    implementation project(path: ':basic-dialogs')
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
}

基本对话框模块级文件

plugins {
    id 'com.android.library'
    id 'org.jetbrains.kotlin.android'
}

android {
    compileSdk 32

    defaultConfig {
        minSdk 27
        targetSdk 32

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
}
3个回答

31

需要将以下内容添加到basic-dialogs模块的build.gradle文件中:

buildFeatures {
    compose true
}
composeOptions {
    kotlinCompilerExtensionVersion compose_version
}

整个Gradle文件

plugins {
    id 'com.android.library'
    id 'org.jetbrains.kotlin.android'
}

android {
    compileSdk 32

    defaultConfig {
        minSdk 27
        targetSdk 32

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
    }
}

dependencies {

    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
}

1
这帮助我节省了很多时间。谢谢。 - Granson
1
谢谢您,先生,您救了我的一天。由于缺少 buildFeatures { compose true } 行,我遇到了这个错误,但现在已经修复 :) - thegirlincode
2
每次我在我的多模块应用程序中遇到这个问题,这个答案都会帮助我解决它。 - Bilal Bangash
2
为什么Android团队不提供一个明智的错误提示呢?这是显而易见的,人们会犯这种错误,但我们却在这里束手无策。 - Daniel Wilson
这需要在一个模块中具有可组合性,除了主应用程序gradle之外。- 感谢您的输入 - undefined

6

希望我能为某人节省掉这3个小时。如果您在多模块项目中使用Compose BOM,并且需要一个与BOM中指定的不同的单个依赖项的更新版本,并且您的模块也共享BOM,则在模块之间共享依赖项时要非常小心。

以我的例子为例:

    implementation(platform(libs.androidx.compose.bom))
    api("androidx.compose.material3:material3:1.1.0-rc01") // Relatively new and needed for date & time pickers

在一个模块中,然后有很多其他的模块依赖于这个模块。其中一些模块也被指定:

implementation(libs.androidx.compose.material3)

这导致应用程序混乱不堪,其中一个模块完全正常,而其他无关的模块在运行时崩溃,告诉我它们不知道什么是TextField。


2
清理构建,然后重新构建解决了我的问题。

绝对,它确实如此! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接