[英]IllegalAccessError: Method is inaccessible to class
我有一個非常奇怪的錯誤,因為它只發生在從生成的.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
}
問題是MyActivity
無法訪問ANIMATION_SLIDE_FROM_RIGHT
。 我會重復一遍,它只發生在手動生成的.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
的animationKind
屬性更改為1
,一切正常。
更新 2
刪除@JvmStatic
和受保護的可見性后,它工作正常。
來自Kotlin 官方文檔:
Java 允許從同一包中的其他類訪問受保護的成員,而 Kotlin 不允許,因此 Java 類可以更廣泛地訪問代碼
因此,請確保您的BaseActivity
和MyActivity
在同一個包下。
如果這兩個活動不在同一個包下,那么它可以通過從 Studio 直接運行完美運行,但是當您生成 .apk 並嘗試通過安裝該 apk 在設備上運行時它會崩潰(IllegalAccessError)。
雖然我不確定為什么會導致 IllegalAccessError,但您應該像這樣定義這些常量:
companion object {
const val ANIMATION_DEFAULT = 0
const val ANIMATION_SLIDE_FROM_RIGHT = 1
const val ANIMATION_SLIDE_FROM_BOTTOM = 2
}
這應該可以解決您的問題,否則使用@JvmField
而不是@JvmStatic
會是更好的選擇。
確保您已在與調用代碼相同的模塊中聲明失敗的方法。
就我而言,我遇到了以下錯誤:
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
模塊后,沒有發現任何問題。
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 靜態成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.