Kotlin Activity not included in APK

2019-08-27 06:22发布

问题:

Am introducing my first Kotlin code (a new activity) into an established Android app. Using Android Studio 2.3.3, Gradle 3.3. I am able to build and run the app but at the point of launching the new Kotlin activity, app crashes with a class not found exception. Analyzing the APK indicates the Kotlin class has not been included in the dex (and its multi-dex, have checked both dex files).

build.gradle (project)

buildscript {
    ext.kotlin_version = '1.1.4'
    repositories {
        jcenter()
        maven { url 'https://maven.fabric.io/public' }
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.google.gms:google-services:3.0.0'

        classpath 'com.github.triplet.gradle:play-publisher:1.1.4'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

        classpath 'io.fabric.tools:gradle:1.+'
        classpath 'me.tatarka:gradle-retrolambda:3.2.5'
        classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.2.1'

        // For automated ui testing
        classpath 'com.stanfy.spoon:spoon-gradle-plugin:1.2.2'

        // For Amazon Device Farm
        classpath 'com.amazonaws:aws-devicefarm-gradle-plugin:1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
        jcenter()
        maven { url 'http://dl.bintray.com/optimizely/optimizely' }
        maven { url "https://jitpack.io" }
        maven { url "http://salesforce-marketingcloud.github.io/JB4A-SDK-Android/repository" }
        flatDir {
            dirs 'libs'
        }
    }
}

build.gradle (app module)

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'io.fabric'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'jacoco'
apply plugin: 'spoon'
repositories {
    mavenCentral()
    maven { url 'https://maven.fabric.io/public' }
    maven { url 'http://salesforce-marketingcloud.github.io/JB4A-SDK-Android/repository' }
    maven { url "https://maven.google.com" }
    maven { url "http://maven.tealiumiq.com/android/releases/" }
}
android {
    compileSdkVersion 25
    buildToolsVersion '25.0.0'

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        targetSdkVersion 25

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        // Enabling multidex support. :(
        multiDexEnabled true

    }

    dexOptions {
        javaMaxHeapSize "8g"
        dexInProcess true // the magic line
    }


    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
        compileOptions.incremental = false
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    //include our modules
    compile project(':core')
    compile project(':data')

    //android
    final APP_COMPAT_VERSION = '25.4.0'
    compile "com.android.support:appcompat-v7:$APP_COMPAT_VERSION"
    compile "com.android.support:recyclerview-v7:$APP_COMPAT_VERSION"
    compile "com.android.support:design:$APP_COMPAT_VERSION"
    compile "com.android.support:multidex:1.0.0"
    compile "com.android.support:cardview-v7:$APP_COMPAT_VERSION"

    // google
    final PLAY_SERVICES_VERSION = '10.2.4'
    compile "com.google.android.gms:play-services-wallet:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-location:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-gcm:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-plus:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-identity:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-analytics:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-auth:$PLAY_SERVICES_VERSION"
    compile "com.google.android.gms:play-services-maps:$PLAY_SERVICES_VERSION"

    compile "org.jetbrains.kotlin:kotlin-stdlib"
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"


    androidTestCompile jUnit

    // Unit tests dependencies
    testCompile jUnit
    testCompile "org.hamcrest:hamcrest-core:$HAMCREST_VERSION"
    testCompile "org.hamcrest:hamcrest-library:$HAMCREST_VERSION"
    testCompile "org.hamcrest:hamcrest-integration:$HAMCREST_VERSION"
    testCompile 'org.robolectric:robolectric:3.1'
    testCompile 'org.mockito:mockito-core:1.+'
    testCompile 'com.google.guava:guava:19.0'
    testCompile("com.android.support:support-v4:$APP_COMPAT_VERSION") {
        exclude module: 'support-annotations'
    }
    testCompile('org.powermock:powermock-api-mockito:1.6.4') {
        exclude module: 'objenesis'
    }
    testCompile('org.powermock:powermock-module-junit4:1.6.4') {
        exclude module: 'objenesis'
    }
    testCompile 'io.reactivex:rxandroid:1.0.1'
    testCompile 'io.reactivex:rxjava:1.1.0'

    // Espresso
    androidTestCompile('com.android.support.test:runner:0.5') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test:rules:0.5') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.2') {
        exclude module: 'support-annotations'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'appcompat-v7'
        exclude module: 'design'
        exclude module: 'support-v4'
    }

    // allows java 8 compile
    compile 'com.annimon:stream:1.1.2'

    uitestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
    developmentCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}

and the activity, which is very simple:

class HyperFlashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(hyperflash_activity_layout)
    }
}

and the launching code:

public static void launchHyperflashActivity(Activity launchingActivity) {
    Intent intent = new Intent(launchingActivity, HyperFlashActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    launchingActivity.startActivity(intent);
    launchingActivity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}

回答1:

I once had the same issue1 and basically the fix was to instead of Android Studio 2.x download the Android Studio 3.0 Beta. This should fix your problem even if the code highlighting does work when using the 2.x version.

When you look at the New Features tab you can see that it features support for Kotlin language which kind of suggests it was lacking before (I think in this case it was just built into Android Studio and enhanced specifically for Android Studio's requirements (such as including the class to the dex file)).

1: with the exception of multidex as I didn't need it