在打
release
包的時候遇到了這個問題,算是比較常見,記一下
解決思路
。
本文介紹了出現這個問題的原因,以及出現問題時
我的建議
和
我的思路
,着急的可以直接看
解決方案
。
異常
Subscriber class xxx and its super classes have no public methods with the @Subscribe annotation
複制
遇到異常不要慌,其實已經提示的很明顯了,指定了具體的
class
,且明确告訴你這個類沒有
@Subscribe
注解。
原因
但其實知道了問題後,可能依然會有疑惑,比如我,因為我這個類是有
@Subscribe
注解的,那是為什麼呢?
因為知道具體的
class
,也知道
@Subscribe
注解,是以很容易就能定位到是
EventBus
。
随後去
EventBus
官網尋找答案,果然
issues
第一頁就有相同的問題,作者團隊是這麼回複的:
Check your R8 / ProGuard rules.
https://github.com/greenrobot/EventBus#r8-proguard
檢查你的壓縮/混淆規則。
這才反應過來,原來開啟了
R8
壓縮導緻的,
minifyEnabled true
buildTypes {
release {
minifyEnabled true
...
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
複制
那為什麼開啟了
R8
壓縮就會導緻上面的異常呢,是因為
EventBus
的注解使用了反射。
反射 (Reflection) 會導緻 R8 在跟蹤代碼時無法識别到代碼的入口點。第三方庫也可能用到反射,并且由于第三方庫實際上是您的應用的一部分,您 (作為應用開發者) 将負責這些庫以及您自己的代碼中使用的反射。第三方庫可能附帶了它們自己的規則,但是切記,有些庫不一定是為 Android 編寫的,抑或是未考慮縮減問題,是以它們可能需要其他配置。
解決方案
明白了前因後果之後,解決方案就應然而生了。
方案一
關閉
R8
壓縮
minifyEnabled false
複制
但是這樣會使得你的應用增大不少,比如你使用了某個第三方庫時,應用中隻使用了其中很小一部分,但打包時所有庫代碼都會保留在應用中。
如果你不介意的話,這是最
簡單粗暴
的解決方案。
作者:https://blog.csdn.net/yechaoa
方案二
添加相應的
壓縮/混淆
規則,比如
EventBus
:
-keepattributes *Annotation*
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# And if you use AsyncExecutor:
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
複制
總結
其實問題并不複雜,關鍵是解決問題的過程,我想傳達以下幾點:
- 遇到問題先不要慌,也不要盲目搜尋答案,這樣會浪費時間,且可能混淆你的視線
- 先認真仔細的看一下
,一般日志都會給你提示日志
- 結合一切可用資訊,快速準确的定位問題
- 如果非要搜,建議先去
找答案官方文檔
我遇到這個異常是怎麼解決的:
- 根據日志提示,我定位到問題是
EventBus
- 檢視使用教程,并沒有發現什麼問題
- 在EventBus的
中看看是否有同樣的問題,果然是有的,并知道了是issues
導緻的R8壓縮
- 去
檢視google官網
相關介紹,并知道了原因,且提供了解決方案R8
舉一反三,也适用其他的問題。
參考
- EventBus
- R8官方文檔