我有一个非常奇怪的错误,因为它仅在从生成的.apk
安装应用程序之后发生。当我尝试通过IDE运行该应用程序时,它运行良好。
java.lang.IllegalAccessError: Method 'int <package>.BaseActivity$Companion.getANIMATION_SLIDE_FROM_RIGHT()' is inaccessible to class '<package>.MyActivity' (declaration of '<package>.MyActivity' appears in /data/app/<package>-mg7eYmJ8hX5WvkNWNZWMVg==/base.apk!classes3.dex)
如您所见,有一个名为BaseActivity
的类,它看起来像这样:
open class BaseActivity : AppCompatActivity() {
companion object {
@JvmStatic
protected val ANIMATION_DEFAULT = 0
@JvmStatic
protected val ANIMATION_SLIDE_FROM_RIGHT = 1
@JvmStatic
protected val ANIMATION_SLIDE_FROM_BOTTOM = 2
}
protected open var animationKind = ANIMATION_DEFAULT
// Some other stuff
}
现在,每个活动都扩展了该类,并且经常像这样覆盖animationKind
:
class MyActivity: BaseActivity() {
override var animationKind = ANIMATION_SLIDE_FROM_RIGHT
// Some other stuff
}
问题是ANIMATION_SLIDE_FROM_RIGHT
无法访问MyActivity
。我将重复一遍,它仅在手动生成的.apk
上发生。有趣的是,我没有使用multidex,但是错误似乎表明BaseActivity
在classes3.dex
中。这是我的gradle文件:
应用插件:“ com.android.application” 应用插件:“ kotlin-android” 应用插件:“ kotlin-android-extensions” 应用插件:“ kotlin-kapt”
android {
compileSdkVersion 28
defaultConfig {
applicationId <package>
versionCode <versionCode>
versionName <versionName>
minSdkVersion 21
targetSdkVersion 28
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
androidExtensions {
experimental = true
}
}
dependencies {
// Dependencies
}
我尝试使用multidexEnabled false/true
,但是唯一的变化是在false
状态下,classes3.dex
后缀消失了。
更新
当然,当我将MyActivity
的{{1}}属性更改为animationKind
时,一切正常。
更新2
在删除1
并保护可见性后,它可以正常工作。
答案 0 :(得分:6)
来自official Kotlin documentation:
Java允许从同一类中的其他类访问受保护的成员 包,而Kotlin没有,所以Java类将具有更广泛的访问权限 到代码
因此,请确保您的flex: 15
和BaseActivity
位于同一软件包中。
如果两个活动都不在同一个程序包中,则可以通过直接从Studio直接运行来完美运行,但是在生成.apk并尝试通过安装该apk在设备上运行时会崩溃(IllegalAccessError)。
答案 1 :(得分:0)
虽然我不确定为什么会导致IllegalAccessError,但是您应该像这样定义这些常量:
companion object {
const val ANIMATION_DEFAULT = 0
const val ANIMATION_SLIDE_FROM_RIGHT = 1
const val ANIMATION_SLIDE_FROM_BOTTOM = 2
}
那应该可以解决您的问题,否则使用@JvmField
代替@JvmStatic
会是一个更好的选择。
答案 2 :(得分:0)
确保已声明与调用代码同一模块内失败的方法。
就我而言,我遇到以下错误:
java.lang.IllegalAccessError: Method 'boolean[] my.package.common.kotlin.AndroidExtensionsKt.$jacocoInit()' is inaccessible to class 'my.package.ui.first.FirstActivity$viewModel$2' (declaration of 'my.package.ui.first.FirstActivity$viewModel$2' appears in /data/app/my.package.dev-fdHNodmdXHv-b_heK4MXeA==/base.apk!classes8.dex)
at my.package.ui.first.FirstActivity$viewModel$2.invoke(FirstActivity.kt:18)
at my.package.ui.first.FirstActivity$viewModel$2.invoke(FirstActivity.kt:14)
at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
at my.package.ui.first.FirstActivity.getViewModel(Unknown Source:11)
at my.package.ui.first.FirstActivity.onCreate(FirstActivity.kt:23)
在getViewModel()
模块中声明了common
,在FirstActivity
模块中声明了app
的地方:
inline fun <reified T : ViewModel> FragmentActivity.getViewModel(
factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(this, factory).get(T::class.java)
将getViewModel()
从common
模块移到app
模块后,没有发现问题。
答案 3 :(得分:0)
open class BaseActivity : AppCompatActivity() {
@JvmField
protected val ANIMATION_DEFAULT = 0
@JvmField
protected val ANIMATION_SLIDE_FROM_RIGHT = 1
@JvmField
protected val ANIMATION_SLIDE_FROM_BOTTOM = 2
protected open var animationKind = ANIMATION_DEFAULT
// Some other stuff
}
这个怎么样?
在我看来,Kotlin 还没有完全支持伴侣——jvm 静态成员。