将MainActivity转换为Kotlin后,后续构建中的ClassNotFoundException

时间:2015-07-31 22:25:19

标签: android classnotfoundexception kotlin

我想尝试Kotlin,所以我决定尝试将我的项目的单个类转换为Kotlin,并在尝试转换整个项目之前看看它是如何与我的工作流程集成的。我能够构建并且我的应用程序正常工作,但是在第一次构建之后的每个后续构建中,我从ClassLoader获得以下异常。该应用程序仅在清洁后才能正常工作,并在转换任何内容之前正常工作。我能够多次在同一台机器上运行HelloWorld项目而不会出错。这个问题的回答没有帮助:ClassNotFoundException in custom flavor using kotlin

07-31 14:35:41.563    1878-1878/com.ddiehl.android.htn.debug
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.ddiehl.android.htn.debug, PID: 1878
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.ddiehl.android.htn.debug/com.ddiehl.android.htn.view.activities.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.ddiehl.android.htn.view.activities.MainActivity" on path: DexPathList[[zip file "/data/app/com.ddiehl.android.htn.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/com.ddiehl.android.htn.debug-1/lib/arm, /vendor/lib, /system/lib]]
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "com.ddiehl.android.htn.view.activities.MainActivity" on path: DexPathList[[zip file "/data/app/com.ddiehl.android.htn.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/com.ddiehl.android.htn.debug-1/lib/arm, /vendor/lib, /system/lib]]
            at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
    Suppressed: java.lang.ClassNotFoundException: com.ddiehl.android.htn.view.activities.MainActivity
            at java.lang.Class.classForName(Native Method)
            at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
            at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
            ... 13 more
     Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

任何人都知道为什么我的应用可能适用于首次构建,但不适用于后续版本?这是我的build.gradle,manifest和activity,供参考。

build.gradle(app module)

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.jakewharton.hugo'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'me.tatarka.retrolambda'

android {
    compileSdkVersion 22
    buildToolsVersion "23 rc3"
    defaultConfig {
        applicationId "com.ddiehl.android.htn"
        minSdkVersion 15
        targetSdkVersion 22
        versionCode 4
        versionName "0.3.0-dev"
        ndk {
            moduleName "app"
        }
    }
    signingConfigs {
        release {
            storeFile file(ANDROID_KEYSTORE_PATH)
            storePassword ANDROID_KEYSTORE_PWD
            keyAlias HTN_KEYSTORE_ALIAS
            keyPassword HTN_KEYSTORE_PWD
        }
    }
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            minifyEnabled false
        }

        release {
            debuggable false
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
        debug.java.srcDirs += 'src/debug/kotlin'
    }
}

def getLocalProperty(s) {
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    return properties.getProperty(s)
}

retrolambda {
    jdk getLocalProperty("jdk8.dir")
}

dependencies {
    compile project(':reddit')
    compile project(':mopub')
    compile project(':flurry')
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.android.support:support-v4:22.2.1'
    compile 'com.android.support:design:22.2.0'
    compile 'com.android.support:recyclerview-v7:22.2.1'
    compile 'com.android.support:cardview-v7:22.2.1'
    compile 'com.google.android.gms:play-services-ads:7.5.0'
    compile 'com.squareup.okhttp:okhttp:2.4.0'
    compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
    compile 'com.squareup.retrofit:retrofit:1.9.0'
    compile 'com.squareup:otto:1.3.5'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.jakewharton:butterknife:7.0.0'
    compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
    compile 'io.reactivex:rxandroid:0.25.0'
    compile 'com.facebook.stetho:stetho:1.1.1'
    compile 'com.facebook.stetho:stetho-okhttp:1.1.1'
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
}

buildscript {
    ext.kotlin_version = '0.12.1230'
    repositories {
        mavenCentral()
        maven {
            url 'http://oss.sonatype.org/content/repositories/snapshots'
        }
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

repositories {
    mavenCentral()
    maven {
        url 'http://oss.sonatype.org/content/repositories/snapshots'
    }
}

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ddiehl.android.htn" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:name="com.ddiehl.android.htn.HoldTheNarwhal"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:supportsRtl="true">

        <meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name="com.ddiehl.android.htn.view.activities.MainActivity"
            android:label="@string/app_name"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="www.damiendiehl.net"
                    android:scheme="http" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.kt(我编辑了大部分与视图相关的逻辑,它是400行,目前这是一个闭源项目。但是,如果需要,我可以将整个文件粘贴到一起)。

package com.ddiehl.android.htn.view.activities

import android.app.Dialog
import android.app.ProgressDialog
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.support.design.widget.NavigationView
import android.support.design.widget.Snackbar
import android.support.v4.content.ContextCompat
import android.support.v4.view.GravityCompat
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.MenuItem
import android.view.View
import android.view.Window
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import butterknife.Bind
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.bindView
import com.flurry.android.FlurryAgent
import com.flurry.android.FlurryAgentListener
import com.mopub.common.MoPub
import com.mopub.mobileads.MoPubConversionTracker
import hugo.weaving.DebugLog
import java.util.HashMap
import kotlin.properties.Delegates

public class MainActivity : AppCompatActivity(), MainView, ConfirmSignOutDialog.Callbacks, NavigationView.OnNavigationItemSelectedListener {

    private val mBus = BusProvider.getInstance()
    private var mMainPresenter: MainPresenter? = null
    private var mLastAuthCode: String? = null

    private var mProgressBar: ProgressDialog? = null
    private var mSubredditNavigationDialog: Dialog? = null

    val mDrawerLayout: DrawerLayout by bindView(R.id.drawer_layout)

    private var mAccessTokenManager: AccessTokenManager? = null

    DebugLog
    override fun onCreate(savedInstanceState: Bundle?) {
        super<AppCompatActivity>.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ButterKnife.bind(this@MainActivity)

        Init().execute()
    }

    private inner class Init : AsyncTask<Void, Void, Void>() {
        override fun onPreExecute() {
            super.onPreExecute()

            mNavigationView.setNavigationItemSelectedListener(this@MainActivity)

            val toolbar = ButterKnife.findById<Toolbar>(this@MainActivity, R.id.toolbar)
            setSupportActionBar(toolbar)
            val actionBar = getSupportActionBar()
            if (actionBar != null) {
                actionBar.setHomeAsUpIndicator(R.drawable.ic_navigation_menu)
                actionBar.setDisplayHomeAsUpEnabled(true)
            }
        }

        override fun doInBackground(vararg params: Void): Void? {
            mAccessTokenManager = AccessTokenManager.getInstance(this@MainActivity)
            return null
        }

        override fun onPostExecute(aVoid: Void?) {
            super.onPostExecute(aVoid)
            onAppInitialized()
        }
    }

    override fun onStart() {
        super<AppCompatActivity>.onStart()

        if (mAccessTokenManager == null) {
            showSpinner(R.string.application_loading)
        } else {
            onAppInitialized()
        }
    }

    private fun onAppInitialized() {
        mBus.register(mAccessTokenManager)

        FlurryAgent.onStartSession(this)
        dismissSpinner()
        updateUserIdentity()
        showSubredditIfEmpty(null)
    }

    override fun onStop() {
        super<AppCompatActivity>.onStop()
        FlurryAgent.onEndSession(this)
        mBus.unregister(mAccessTokenManager)
    }

    companion object {
        public val TAG: String = javaClass<MainActivity>().getSimpleName()

        private val DIALOG_CONFIRM_SIGN_OUT = "dialog_confirm_sign_out"
        private val FLURRY_SESSION_TIMEOUT_SECONDS = 30
    }

}

2 个答案:

答案 0 :(得分:1)

一个可能的原因可能是注释处理库。

答案 1 :(得分:1)

将现有的 Android 应用程序从 Java 转换为 Konlin 时,需要进行许多配置更改。如果您只将实际的 Java 文件转换为 Kotlin,则编译会起作用,但您会遇到那些运行时加载错误。 最简单的方法是在项目中添加一个 Kotlin 类:

新建->kotlin 类/文件

然后,Android 工作室将进行所有必要的设置以支持 kotlin。删除新类后