Android Jetpack Compose - java.lang.NoSuchMethodError: No virtual method setContent(Lkotlin/jvm/functions/Function0;)

Viewed 3863

I'm getting a java.lang.NoSuchMethodError exception when trying to run setContent{ Composable() }.

Full code:

class ComposeFragment : Fragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
        ComposeView(requireContext()).apply { setContent { Text("hello") } }

}

Full exception:

java.lang.NoSuchMethodError: No virtual method setContent(Lkotlin/jvm/functions/Function0;)V in class Landroidx/compose/ui/platform/ComposeView; or its super classes (declaration of 'androidx.compose.ui.platform.ComposeView' appears in /data/app/~~3OmVKUoYitZ_S4H81xmyuw==/my.app.package-PAQxAKmtRuhnzp4M2DME8w==/base.apk)

Solutions/answers to similar questions suggest adding buildFeatures { compose = true } or kotlinCompilerExtensionVersion, I have already done this but the issue persists.

My full compose Gradle config is as follows:

kotlinOptions {
    jvmTarget = JavaVersion.VERSION_1_8.toString()
    useIR = true
}

buildFeatures {
    compose = true
}

composeOptions{
    kotlinCompilerExtensionVersion = "1.0.5"
}

implementation( "androidx.activity:activity-compose:1.3.1" )
implementation( "androidx.activity:activity-compose:1.3.1" )
implementation( "androidx.compose.material:material:1.0.5" )
implementation( "androidx.compose.animation:animation:1.0.5" )
implementation( "androidx.compose.ui:ui-tooling:1.0.5" )
implementation( "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07" )
androidTestImplementation( "androidx.compose.ui:ui-test-junit4:1.0.5" )
7 Answers

Ran into the same exception today, so I put my solution here in case someone else needs it.

In my case, it was because the setup below was missing from the build.gradle file. enter image description here

Version.COMPOSE is the compose version, in my case it was 1.1.0-alpha05

Your Compose version is very old and is almost certainly the reason for your problems. Update your project gradle with the following. Make sure to upgrade the plugin versions as well:

buildscript {
    ext {
        compose_version = '1.1.0-rc01'
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.1.0'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0'
    }
}

Make sure all your dependencies are using the most recent stable version.

You should also update your Kotlin plugin version:

211-1.6.10-release-923-AS7442.40

If you don't know where to set this, click on:

Android Studio > Preferences > Languages & Frameworks > Kotlin

Finally, I strongly recommend that you use Java 11 instead of 8 and set your app's build.gradle to this:

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

apply from: 'codeinc.gradle'

android {
    compileSdkVersion 31
    buildToolsVersion "31.0.0"

    defaultConfig {
        applicationId "mydomain.myapp.blablahblah"
        minSdkVersion 21
        targetSdkVersion 31
        versionName "1.0.0"
        
        versionCode 1
    }
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = '11'
        useIR = true
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
        kotlinCompilerVersion '1.6.0'
    }
}

I had the same issue and it was solved by adding the following lines to my app's build.gradle file:

android {
   buildFeatures {
       compose true
   }
}
@Composable
private fun Greeting() {
    Text(
        text = stringResource(R.string.channel_id),
        style = MaterialTheme.typography.h5,
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 10.dp)
            .wrapContentWidth(Alignment.CenterHorizontally)
    )
}

class ShowAvatarImageActivity : AppCompatActivity() {
    ......
    val greeting = findViewById<ComposeView>(R.id.greeting)
    greeting.setContent {
        Greeting()
    }
    ......
}

Gradle Config such as you

My xml file like this

<androidx.constraintlayout.widget.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_gravity="center"
  android:background="#000">

    ......

  <androidx.compose.ui.platform.ComposeView
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    android:id="@+id/greeting"
    android:layout_width="match_parent"
    android:layout_height="200dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

I use pure Kotlin code for a comparison of separate functions to test

Add to build.gradle.kts

android {
    buildFeatures {
        compose = true
    }

    composeOptions {
        kotlinCompilerVersion = Depends.kotlin
        kotlinCompilerExtensionVersion = Depends.compose
    }
}

For integration of composeView you must have to add below dependency; implementation 'androidx.activity:activity-compose:1.4.0'

Also, don't forget supporting version of kotlin with compose version.

If you are using compose version as 1.1.1 you have to use kotlin version

Add this lines to your module's gradle file :

buildFeatures {
    compose = true
}
composeOptions {
    kotlinCompilerExtensionVersion = rootProject.extra["compose_version"] as String
}

If you work on muli-module project, you have to add this for each compose included modules.

Related