idu*_*olz 3 android parcelable android-r8 android-gradle-plugin-8.0
我最近更新到了 AGP 8,并在 Play 商店上发布了更新。我收到一些最近未更改的代码区域发生崩溃的报告。我相当有信心这是由 AGP 8 升级引起的崩溃,特别是在 R8 全模式周围。
崩溃周围的代码正在恢复布局管理器的状态。
恢复代码
if (savedInstanceState != null) {
oldRecyclerLayoutState = savedInstanceState.getParcelableCompat(
SIS_RECYCLER_LAYOUT_STATE,
)
}
Run Code Online (Sandbox Code Playgroud)
保存实例代码
private lateinit var layoutManager: LinearLayoutManager
...
override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelable(SIS_RECYCLER_LAYOUT_STATE, layoutManager.onSaveInstanceState())
super.onSaveInstanceState(outState)
}
Run Code Online (Sandbox Code Playgroud)
Class.isAssignableFrom()崩溃报告表明,读取 Parcelable 会崩溃,因为调用类时其 ifTable 为 null 。从AOSP中,我可以看到 anifTable是一个接口表。我假设isAssignableFrom正在使用 来ifTable确定可分配性,但是由于类为空,它无法读取它。不幸的是,该错误没有告诉我哪个类为空。
完整的堆栈跟踪:
Fatal Exception: java.lang.NullPointerException: Attempt to read from field 'java.lang.Object[] java.lang.Class.ifTable' on a null object reference in method 'boolean java.lang.Class.isAssignableFrom(java.lang.Class)'
at java.lang.Class.isAssignableFrom(Class.java:579)
at android.os.Parcel.readParcelableCreatorInternal(Parcel.java:4865)
at android.os.Parcel.readParcelableInternal(Parcel.java:4778)
at android.os.Parcel.readValue(Parcel.java:4544)
at android.os.Parcel.readValue(Parcel.java:4324)
at android.os.Parcel.-$$Nest$mreadValue()
at android.os.Parcel$LazyValue.apply(Parcel.java:4422)
at android.os.Parcel$LazyValue.apply(Parcel.java:4381)
at android.os.BaseBundle.getValueAt(BaseBundle.java:394)
at android.os.BaseBundle.getValue(BaseBundle.java:374)
at android.os.BaseBundle.getValue(BaseBundle.java:357)
at android.os.BaseBundle.get(BaseBundle.java:696)
at android.os.Bundle.getParcelable(Bundle.java:947)
at com.ggstudios.lolcatalyst.util.ext.BundleExtKt.getParcelableCompat(BundleExt.kt:21)
at com.ggstudios.lolcatalyst.summonerlookup.SummonerProfileFragment.onViewCreated(SummonerProfileFragment.kt:422)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3137)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1435)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2979)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2890)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3138)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1435)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2979)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2897)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:263)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:351)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:251)
at com.ggstudios.lolcatalyst.activity.abs.BaseActivity.onStart(BaseActivity.kt:90)
at com.ggstudios.lolcatalyst.activity.MainActivity.onStart(MainActivity.kt)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1510)
at android.app.Activity.performStart(Activity.java:8603)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4191)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Run Code Online (Sandbox Code Playgroud)
如果有人知道原因或解决方法是什么,将不胜感激!
tl;dr 修复方法是使用BundleCompat.getParcelable(Bundle, String, Class)fromandroidx.core:core-ktx:1.10.0而不是getParcelable(String, Class).
我认为这次事故是由两件事不幸结合造成的。
getParcelable(String, Class)如果 Parcelable 没有以特定方式定义,则 API 33 中引入的新方法会存在一些错误。此处记录了这一点。看来getParcelable(String, Class)R8 优化某些代码的脆弱实现导致了这次崩溃。目前的修复似乎是使用getParcelable(String)API 33 中的旧方法。Google 表示他们已经getParcelable(String, Class)在 API 34 中修复了该问题。
更新:androidx.core:core-ktx:1.10.0包含此问题的修复。它包含BundleCompat.getParcelable(Bundle, String, Class)只会getParcelable(Bundle, Class)在Android U及以上版本上调用新功能。
| 归档时间: |
|
| 查看次数: |
802 次 |
| 最近记录: |