Из-за чего может появляться исключение kotlin.TypeCastException для Activity?
В консоли Google Play смотрю отчет по ошибкам и вижу следующее:
kotlin.TypeCastException:
at com.app.android.ui.SplashFragment.loadAds (SplashFragment.java:111)
at com.app.android.ui.SplashFragment$requestConsentInfoUpdate$1.onConsentInfoUpdated (SplashFragment.java:68)
at com.google.ads.consent.ConsentInformation$ConsentInfoUpdateTask.onPostExecute (ConsentInformation.java:277)
at com.google.ads.consent.ConsentInformation$ConsentInfoUpdateTask.onPostExecute (ConsentInformation.java:188)
at android.os.AsyncTask.finish (AsyncTask.java:632)
at android.os.AsyncTask.access$600 (AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage (AsyncTask.java:645)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:145)
at android.app.ActivityThread.main (ActivityThread.java:5942)
at java.lang.reflect.Method.invoke (Method.java)
at java.lang.reflect.Method.invoke (Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1195)
Также гугл предоставляет дополнительную. информацию по ошибке:

Я пытался запустить приложение на разных версиях Android, но у меня ошибки не возникало
Приложение состоит из одного активити (MainActivity) и нескольких фрагментов.
Метод в SplashFragment, на котором появляется ошибка:
fun loadAds() {
(activity as MainActivity).forceShowAd(callback = { // <- вот тут возникает исключение
Log.i(TAG, "load ads");
(activity as MainActivity).toMain()
})
}
Вызываемый метод в MainActivity:
fun forceShowAd(callback: () -> Unit) {
Log.i(TAG, "forceShowAd")
run {
val mInterstitialAd = InterstitialAd(this)
mInterstitialAd.apply {
adUnitId = getString(R.string.admob_inter)
adListener = object : AdListener() {
override fun onAdLoaded() {
callback()
show()
}
override fun onAdFailedToLoad(p0: Int) {
super.onAdFailedToLoad(p0)
var mStartAppAd = StartAppAd(applicationContext)
mStartAppAd.loadAd(object : AdEventListener {
override fun onReceiveAd(ad: Ad) {
mStartAppAd.showAd()
callback()
}
override fun onFailedToReceiveAd(ad: Ad) {
callback()
}
})
}
}
loadAd(getAdRequest())
}
}
}
Вот так запускается SplashFragment в MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, SplashFragment.newInstance())
.commit()
}
}
Исходя из жизненного цикла приложения, пока работает фрагмент, должно работать и активити. Но при этом, как я понял, на момент срабатывания исключения activity == null
Из-за чего может возникать проблема с исключением? Такая проблема встречается аж на 6% устройств
Ответы (1 шт):
Фрагмент может в любой момент перейти состояние "отключен от активити".
При выполнении асинхронных операций в фрагменте нужно всегда об этом помнить. Пока она выполняется, может произойти что угодно. Никто не гарантирует что если активити при старте операции была, то останется и при ее окончании.
В вашем случае нужно писать null-безопасный код типа:
(activity as? MainActivity)?.forceShowAd(callback = {
Log.i(TAG, "load ads");
(activity as? MainActivity)?.toMain()
})