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);
}