简体   繁体   中英

Compose Runtime can't find my custom theme

Trying to play around with Jetpack Compose and got stuck in the first activiity itself.

My App crashes on launch with below exception:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.chanse.locals.cerve.dev, PID: 19105
java.lang.NoSuchMethodError: No static method ChanseTheme(ZLkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V in class Lio/chanse/locals/commonui/theme/ChanseThemeKt; or its super classes (declaration of 'io.chanse.locals.commonui.theme.ChanseThemeKt' appears in /data/app/io.chanse.locals.cerve.dev-E-UJEroB15OQtmBe0WnvGw==/base.apk!classes5.dex)
    at io.chanse.locals.cerve.location.LocationActivity.Screen(LocationActivity.kt:45)
    at io.chanse.locals.cerve.location.LocationActivity$onCreate$1.invoke(LocationActivity.kt:39)
    at io.chanse.locals.cerve.location.LocationActivity$onCreate$1.invoke(LocationActivity.kt:38)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:121)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:46)
    at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:333)
    at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:179)
    at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:178)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:121)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:46)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:193)
    at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:148)
    at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:114)
    at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:113)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:121)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:46)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:193)
    at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:106)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:162)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$3.invoke(Wrapper.android.kt:161)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:121)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:46)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:193)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:161)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:144)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:121)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.kt:46)
    at androidx.compose.runtime.ComposerKt.invokeComposable(Composer.kt:3418)
    at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:2600)
    at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:348)
    at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:693)
    at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:304)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:144)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:135)
    at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:603)
    at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:135)
E/AndroidRuntime:     at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:187)
    at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
    at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:196)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:142)
    at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:135)
    at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:667)
    at android.view.View.dispatchAttachedToWindow(View.java:21304)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4239)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4246)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4246)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4246)
    at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:4246)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2571)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2225)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9126)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:999)
    at android.view.Choreographer.doCallbacks(Choreographer.java:797)
    at android.view.Choreographer.doFrame(Choreographer.java:732)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:984)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:237)
    at android.app.ActivityThread.main(ActivityThread.java:8173)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

Here is my Activity code ( :app module):

class LocationActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Screen()
        }
    }

    @Composable
    fun Screen() {
        ChanseTheme {
            Column(
                verticalArrangement = Arrangement.Center
            ) {
                PinCodeField()
            }
        }
    }

    @Composable
    fun PinCodeField() {
        var text by rememberSaveable { mutableStateOf("") }
        OutlinedTextField(
            value = text,
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            onValueChange = { text = it },
            label = { Text(stringResource(R.string.ask_pincode)) },
            leadingIcon = { Icon(Icons.Filled.LocationOn, null) },
            trailingIcon = { Icon(Icons.Filled.ArrowForward, null) },
            singleLine = true,
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
        )
    }
}

Here is my Theme present in ChanseTheme.kt ( :commonui module)

@Composable
fun ChanseTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    MaterialTheme(
        colors = if (darkTheme) DarkColors else LightColors,
    ) {
        content()
    }
}

And my colors present in ChanseColors.kt ( :commonui module)

val DarkColors = darkColors(
    primary = Purple200,
    primaryVariant = Purple600,
    secondary = Green200,
    secondaryVariant = Green500,
    background = Black900,
    surface = Black800,
    error = Red200,
    onPrimary = Black900,
    onSecondary = Black900,
    onBackground = White50,
    onSurface = White50,
    onError = Black900
)

val LightColors = lightColors(
    primary = Purple500,
    primaryVariant = Purple700,
    secondary = Green200,
    secondaryVariant = Green500,
    background = White50,
    surface = White50,
    error = Red600,
    onPrimary = White50,
    onSecondary = Black900,
    onBackground = Black900,
    onSurface = Black900,
    onError = White50
)

FYI: Here is the dependecies: ( :buildSrc module)

object Activity {
    const val activityCompose = "androidx.activity:activity-compose:1.3.0-alpha04"
}

object Compose {
    const val version = "1.0.0-beta02"

    const val runtime = "androidx.compose.runtime:runtime:$version"
    const val runtimeLivedata = "androidx.compose.runtime:runtime-livedata:$version"
    const val material = "androidx.compose.material:material:$version"
    const val icon = "androidx.compose.material:material-icons-core:$version"
    const val iconX = "androidx.compose.material:material-icons-extended:$version"
    const val foundation = "androidx.compose.foundation:foundation:$version"
    const val layout = "androidx.compose.foundation:foundation-layout:$version"
    const val ui = "androidx.compose.ui:ui:$version"
    const val tooling = "androidx.compose.ui:ui-tooling:$version"
    const val animation = "androidx.compose.animation:animation:$version"
    const val uiTest = "androidx.compose.ui:ui-test-junit4:$version"
}

object Lifecycle {
    const val viewModelCompose = "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha03"
}

The above dependencies are present in :commonui module as api and the entire module is used as dependency in :app module.

What could go wrong here? Any help would be appreciated.

I believe this is a bug. I get the same error when I run Previews on a real device sometimes. So I suggest:

  • Making sure you're running the Activity and not the Preview (check the selected run configuration next to the run button)

  • Try to run on the emulator

Compose tooling is quite unstable at the moment, in my experience. Be prepared to do things like invalidate cache, alternate compose versions to force some kind of reset, etc.

I fixed it with below changes:

Moved my ChanseTheme.kt and ChanseColors.kt files from :commonui module to :app module and it started working.

But I am not sure, why it doesn't work if those two files were present in my :commonui module.

在此处输入图像描述

This issue was caused because your :commonui doesn't configure build.gradle file in an appropriate for jetpack compose way:

android {
   
    buildFeatures {
        compose true
    }
    
    composeOptions {
        kotlinCompilerVersion = kotlin_version
        kotlinCompilerExtensionVersion = compose_version
    }
   
    
    kotlinOptions {
        jvmTarget = '1.8'
        useIR = true
    }
}

Try to configure :commonui and all traversal modules in this way and it should work.

Traversal modules:

for example you have the next module graph -> :commonui -> A -> module_which_has_a_problem In this situation, you have to configure module A in the same way

buildFeatures {
    compose true
}

composeOptions {
    kotlinCompilerVersion = kotlin_version
    kotlinCompilerExtensionVersion = compose_version
}

These two blocks are needed in each modules using compose, even when you are importing the compose dependencies in a common module.

It seems that this issue is because you're using the multiplatform plugin. If your :commonui module was pure android ("kotlin-android" instead of "org.jetbrains.kotlin.multiplatform") it would run without crashes.

In order to fix this and keep using multiplatform, simply add this plugin on your module: id("org.jetbrains.compose").version("1.1.0") . You may also need to add this as a repository: maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM