Ivan Mitsura
Ivan Mitsura

Reputation: 501

Compose into existing project, No virtual method Int

Cant make compose run in existing kotlin/native project for month now, trying to set default Greeting example to splash instead of its ui, cant make it:

java.lang.NoSuchMethodError: No virtual method Int$class-SplashActivity()I in class Lcom/a/b/c/activity/LiveLiterals$SplashActivityKt; or its super classes (declaration of 'a.b.c.ui.activity.LiveLiterals$SplashActivityKt' appears in /data/app/a.b.c.develop-7Zjdfjfy762lPctajg==/base.apk!classes29.dex)
    at a.b.c.ui.activity.SplashActivity.<clinit>
    at java.lang.Class.newInstance(Native Method)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Yes, crash before activity start.

kotlin 1.5.21

compose_version = 1.0.2

mTargetSdkVersion=30(I'm tired of merging manifests every sync, so no 31 until I'l run it all)

mCompileSdkVersion=31

mMinSdkVersion=21

project level build.gradle:

    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath "com.android.tools.build:gradle:7.1.0-alpha12"
    classpath "gradle.plugin.com.wiredforcode:gradle-spawn-plugin:0.8.2"
    classpath "com.google.gms:google-services:4.3.10"
    classpath "com.google.firebase:firebase-crashlytics-gradle:2.7.1"

android module build.gradle(not whole file, its existing project):

implementation "com.android.support:recyclerview-v7:28.0.0"
implementation "com.android.support.constraint:constraint-layout:2.0.4"
implementation "com.android.support:cardview-v7:28.0.0"

implementation "androidx.activity:activity-ktx:1.4.0-alpha02"
implementation "androidx.appcompat:appcompat:1.4.0-alpha03"
implementation "com.google.accompanist:accompanist-appcompat-theme:0.18.0"
implementation "com.google.android.material:material:1.5.0-alpha03"

implementation "androidx.navigation:navigation-fragment-ktx:2.4.0-alpha09"
implementation "androidx.navigation:navigation-compose:2.4.0-alpha09"

implementation 'androidx.core:core-ktx:1.7.0-beta01'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0-beta01'

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.activity:activity-compose:1.4.0-alpha02'

implementation "androidx.tracing:tracing-ktx:1.0.0"

implementation "androidx.multidex:multidex:2.0.1"


implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"

also contains pushwoosh, appsflyer, crashlytics, junit tests(does impact compose libs?)

EDIT: pushwoosh, appsflyer, crashlytics was removed for sake of test, fixed nothing.

Downgrade to compose 1.0.1 and stable androidx did nothing

Upvotes: 7

Views: 1505

Answers (5)

richardleggett
richardleggett

Reputation: 424

Here is the issue in the issue tracker, plus a bunch of workarounds (the cleanest is maybe renaming files in your main source set e.g. CommonSomeModule.kt leaving SomeModule.kt for the flavors).

https://issuetracker.google.com/issues/196063128

Upvotes: 0

Michał Tajchert
Michał Tajchert

Reputation: 10383

I had exactly same error with io.insert-koin:koin-android:3.4.3 (also when adding Compose to the project).

In my case Compose/Koin had trouble with class:

class InAppImpl(val context: Context) : InApp, KoinComponent {
    private val preferences: SharedPreferences by inject()
// ...
}

I changed it to:

class InAppImpl(val context: Context, val preferences: SharedPreferences) : InApp {
// ...
}

And it solved the issue.

Thanks @Danilo Bargen for pointing into right direction as adding @NoLiveLiterals also worked in my case (but it is a workaround and not a true solution).

Upvotes: 0

Danilo Bargen
Danilo Bargen

Reputation: 19472

If you analyze the exception message closely, you might notice the mention of LiveLiterals:

java.lang.NoSuchMethodError: No virtual method Int$class-SplashActivity()I in class Lcom/a/b/c/activity/LiveLiterals$SplashActivityKt;

The LiveLiterals part is not a part of your own API, but it's generated code by Compose, that enables the live editing of literals in the compose preview: https://developer.android.com/jetpack/compose/tooling#live-edit-literals

It seems that for one of your classes (in this case SplashActivity) the LiveLiterals support cannot be generated properly. I don't know if this is a bug in Compose or a known limitation, but as a workaround there is a way to opt out of live literals: https://developer.android.com/reference/kotlin/androidx/compose/runtime/NoLiveLiterals

So if you have a class for which you get the NoSuchMethodError exception, add the @NoLiveLiterals annotation:

@NoLiveLiterals
class SplashActivity {
   // ...

The annotation may be added to a property, a function, a class or an entire file.

Upvotes: 6

Ivan Mitsura
Ivan Mitsura

Reputation: 501

//contains 99% common code, now contains Compose view 
open class AppLegasyFlavorActivity

//absolutely empty for default flavor
class SplashActivity : AppLegasyFlavorActivity()

You can't have that for some reason with 1.0.2 compose. Your child must have onCreate overriden(even if its just super call). I removed legasy parent stuff, did flavors refactor and everything worked. This weird bug resulted as kotlin cant understand Int class. On the edge of technology ways, I guess.

Upvotes: 1

Eyosiyas
Eyosiyas

Reputation: 1507

The issue is that your compile SDK is 31, you are targetting API 31 (Android 12) and not setting the exported attribute.

You need to specify android:exported="true" in the manifest.

If your app targets Android 12 and contains activities, services, or broadcast receivers that use intent filters, you must explicitly declare the android: exported attribute for these app components.

<activity
    android:name=".SplashActivity"
    android:exported="true"
    android:theme="@style/Theme.Demo.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

For more info check the documentation.

Upvotes: -1

Related Questions