带有产品风味和Kotlin的ClassNotFoundException
我有一个主要在Kotlin编写的项目,但有一些Java类。 现在项目进展顺利,我想增加在不同的环境之间切换的可能性,为此我使用了风味:
productFlavors { prod { dimension "default" buildConfigField 'boolean', 'FABRIC', 'true' applicationId = "com.myapp" } beta { dimension "default" buildConfigField 'boolean', 'FABRIC', 'true' applicationId = "com.myapp.beta" } dev { dimension "default" buildConfigField 'boolean', 'FABRIC', 'false' applicationId = "com.myapp.dev" } }
然而,当我运行的味道是不生产(这不会改变applicationId),我得到一个Java类的ClassDefNotFoundException:
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.myapp.beta.ui.view.ScrollBehavior" on path: DexPathList[[zip file "/data/app/com.myapp.beta-1/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.beta-1/lib/arm64, /system/lib64, /vendor/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:380) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 33 more
我正在使用Android Studio 3.0 beta 4和Kotlin插件版本1.1.3-2。
构建文件:
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' // Use experimental kapt implementation repositories { mavenCentral() maven { url "http://dl.bintray.com/ttymsd/maven" } maven { url 'https://jitpack.io' } } android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { applicationId "com.myapp" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } sourceSets { main.java.srcDirs += 'src/main/java' } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } flavorDimensions "default" productFlavors { prod { dimension "default" buildConfigField 'boolean', 'FABRIC', 'true' applicationId = "com.myapp" } beta { dimension "default" buildConfigField 'boolean', 'FABRIC', 'true' applicationId = "com.myapp.beta" } dev { dimension "default" buildConfigField 'boolean', 'FABRIC', 'false' applicationId = "com.myapp.dev" } } dataBinding { enabled = true } dependencies { (...) } }
表现:
代码中的相关部分:
你正在定义你的行为
app:layout_behavior=".ui.view.ScrollBehavior"
这是一个相对的定义。 在这种情况下,相对于应用程序包。
所以实际使用的名称是context.getPackageName() + name
,因此您定义的应用程序ID被用作前缀。
要加载正确的行为,您必须将其定义为完全限定的名称
app:layout_behavior="com.myapp.ui.view.ScrollBehavior"
你也可以在这里使用字符串资源。
这不是一个Kotlin问题。
引起:java.lang.ClassNotFoundException:没有find类“com.myapp。beta .ui.view.ScrollBehavior”
从Android 文档
每个Android应用程序都有一个唯一的应用程序ID,看起来像一个Java包名称,比如com.example.myapp。 此ID在设备和Google Play商店中唯一标识您的应用
或有时我甚至看到(从来没有使用过) :
改变它意味着你正在改变你的应用程序包的参考。 位于com.myapp
的类将被搜索到com.myapp.beta
。 然后你的课程将不会被find。
与之合作的一种方式是将风格定义为(为了简单,我放弃了其他价值观) :
prod { applicationId = "com.myapp" } beta { applicationId = "com.myapp.beta" } dev { applicationId = "com.myapp.dev" }
要不就
beta { applicationIdSuffix ".beta" } dev { applicationIdSuffix ".dev" }
在pusblish build.gradle之后编辑
注意添加一个后缀或一个完整的applicationId:
//This will be append to your application id //applicationIdSuffix = "com.myapp.beta", should be applicationIdSuffix = ".beta"
要么
//This will replace your application Id applicationId "com.myapp.beta"