英文:
Android - DialogFragment With Serializable Callback Crashes on Fragment Destruction
问题
以下是你提供的内容的翻译:
我的片段中包含一个对话框片段,并且为了在对话框的按钮被点击时接收回调,我将一个可序列化的接口传递给它的参数。
问题是,每当对话框显示时,如果用户切换到 Android 主屏幕,应用程序就会崩溃。
注意:根据我的日志,销毁顺序从主片段开始,以对话框片段结束。
初始化对话框片段的代码:
Navigation.findNavController(binding.root).navigate(GameFragmentDirections.actionGameFragmentToPauseDialogFragment(
object : PauseDialogFragment.ResumeGameListener {
override fun onResume() {
isGamePaused = false
onStartGame(_screenSizePairXY)
}
}))
可序列化的回调接口:
interface ResumeGameListener : Serializable {
fun onResume()
}
堆栈跟踪信息:
java.lang.RuntimeException: 在写入可序列化对象时遇到 Parcelable 遇到 IOException (名称 = ui.game.GameFragment$onGameOver$1)
// 具体的堆栈跟踪信息...
Caused by: java.io.NotSerializableException: com.developerkurt.ghosky.ui.game.GameFragment
// 具体的堆栈跟踪信息...
请注意,以上内容是你提供的信息的翻译。如果你还有其他需要帮助的地方,请随时告诉我。
英文:
My fragment has a dialog fragment and to receive a callback when the dialog's button is clicked, I pass a serializable interface to its arguments.
The problem is, whenever the dialog is displayed if the user switches to the android home screen, the app crashes.
NOTE: According to my logs, destruction order is starting from the main fragment and ending with the dialog fragment.
<br><br>
Code to init dialog fragment:
Navigation.findNavController(binding.root).navigate(GameFragmentDirections.actionGameFragmentToPauseDialogFragment(
object : PauseDialogFragment.ResumeGameListener
{
override fun onResume()
{
isGamePaused = false
onStartGame(_screenSizePairXY)
}
}))
<br><br>
Serializable Callback Interface:
interface ResumeGameListener : Serializable
{
fun onResume()
}
<br><br>
StackTrace
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = ui.game.GameFragment$onGameOver$1)
at android.os.Parcel.writeSerializable(Parcel.java:1714)
at android.os.Parcel.writeValue(Parcel.java:1662)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:875)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579)
at android.os.Bundle.writeToParcel(Bundle.java:1233)
at android.os.Parcel.writeBundle(Parcel.java:915)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:125)
at android.os.Parcel.writeTypedObject(Parcel.java:1516)
at android.os.Parcel.writeTypedList(Parcel.java:1395)
at android.os.Parcel.writeTypedList(Parcel.java:1380)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:51)
at android.os.Parcel.writeParcelable(Parcel.java:1683)
at android.os.Parcel.writeValue(Parcel.java:1589)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:875)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579)
at android.os.Bundle.writeToParcel(Bundle.java:1233)
at android.os.Parcel.writeBundle(Parcel.java:915)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:127)
at android.os.Parcel.writeTypedObject(Parcel.java:1516)
at android.os.Parcel.writeTypedList(Parcel.java:1395)
at android.os.Parcel.writeTypedList(Parcel.java:1380)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:51)
at android.os.Parcel.writeParcelable(Parcel.java:1683)
at android.os.Parcel.writeValue(Parcel.java:1589)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:875)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579)
at android.os.Bundle.writeToParcel(Bundle.java:1233)
at android.app.IActivityManager$Stub$Proxy.activityStopped(IActivityManager.java:4008)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:144)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.io.NotSerializableException: com.developerkurt.ghosky.ui.game.GameFragment
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
at android.os.Parcel.writeSerializable(Parcel.java:1709)
at android.os.Parcel.writeValue(Parcel.java:1662) 
at android.os.Parcel.writeArrayMapInternal(Parcel.java:875) 
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) 
at android.os.Bundle.writeToParcel(Bundle.java:1233) 
at android.os.Parcel.writeBundle(Parcel.java:915) 
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:125) 
at android.os.Parcel.writeTypedObject(Parcel.java:1516) 
at android.os.Parcel.writeTypedList(Parcel.java:1395) 
at android.os.Parcel.writeTypedList(Parcel.java:1380) 
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:51) 
at android.os.Parcel.writeParcelable(Parcel.java:1683) 
at android.os.Parcel.writeValue(Parcel.java:1589) 
at android.os.Parcel.writeArrayMapInternal(Parcel.java:875) 
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) 
at android.os.Bundle.writeToParcel(Bundle.java:1233) 
at android.os.Parcel.writeBundle(Parcel.java:915) 
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:127) 
at android.os.Parcel.writeTypedObject(Parcel.java:1516) 
at android.os.Parcel.writeTypedList(Parcel.java:1395) 
at android.os.Parcel.writeTypedList(Parcel.java:1380) 
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:51) 
at android.os.Parcel.writeParcelable(Parcel.java:1683) 
at android.os.Parcel.writeValue(Parcel.java:1589) 
at android.os.Parcel.writeArrayMapInternal(Parcel.java:875) 
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) 
at android.os.Bundle.writeToParcel(Bundle.java:1233) 
at android.app.IActivityManager$Stub$Proxy.activityStopped(IActivityManager.java:4008) 
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:144) 
at android.os.Handler.handleCallback(Handler.java:873) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:193) 
at android.app.ActivityThread.main(ActivityThread.java:6762) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
答案1
得分: 2
使用Parcelable而不是Serializable已经解决了这个问题。然而,当导航时,我仍然会收到一个IllegalArgumentException异常,显示:“无法从当前目标找到当前动作/目标”。但它不会导致应用崩溃或造成任何副作用(至少在我的应用中是如此,我建议你运行测试用例)。
注意:以防万一,我已经将这个代码块包裹在try-catch中。
初始化对话框片段的代码:
try
{
Navigation.findNavController(binding.root).navigate(GameFragmentDirections.actionGameFragmentToPauseDialogFragment(
object : PauseDialogFragment.ResumeGameListener
{
override fun onResume()
{
isGamePaused = false
onStartGame(_screenSizePairXY)
}
override fun writeToParcel(p0: Parcel?, p1: Int)
{
}
override fun describeContents(): Int = 0
}))
}
catch (e: Exception)
{
Timber.w(e.fillInStackTrace())
}
Parcelable回调接口:
interface ResumeGameListener : Parcelable
{
fun onResume()
}
英文:
Using Parcelable instead of Serializable has solved the issue. However, I still do get an IllegalArgumentException exception saying: "current action/destination cannot be found from the current destination" when navigating.
<br>But it doesn't crash the app or cause any kind of side effects (at least in my app, I'd suggest you run test cases).
Note: Just in case I have wrapped the block in try-catch.
Code to init dialog fragment:
try
{
Navigation.findNavController(binding.root).navigate(GameFragmentDirections.actionGameFragmentToPauseDialogFragment(
object : PauseDialogFragment.ResumeGameListener
{
override fun onResume()
{
isGamePaused = false
onStartGame(_screenSizePairXY)
}
override fun writeToParcel(p0: Parcel?, p1: Int)
{
}
override fun describeContents(): Int = 0
}))
}
catch (e: Exception)
{
Timber.w(e.fillInStackTrace())
}
Parcelable Callback Interface:
interface ResumeGameListener : Parcelable
{
fun onResume()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论