AndroidX:Parcelable 仅在 Android 版本 10 设备中遇到写入可序列化对象的 IOException
AndroidX : Parcelable encountered IOException writing serializable object only in Android version 10 devices
我得到了 Parcelable encountered IOException writing serializable object
,它是由 java.io.NotSerializableException: androidx.appcompat.widget.Toolbar
错误引起的,仅在 Android 版本 10 设备中。
我搜索了很多结果来解决这个问题,但我得到的每一个解决方案都告诉我在 inner class 中定义 implement serializable
和 sub inner class 我已经做到了,但是,我只在 Android 版本 10 设备中遇到这个错误。
如果我将使用 transient
这个关键字来定义视图或对象,那么这个错误将得到修复,但同样的错误会出现在另一个视图、适配器和 class.
Logcat
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.android.ui.fragment.CustomViewFragment)
at android.os.Parcel.writeSerializable(Parcel.java:1850)
at android.os.Parcel.writeValue(Parcel.java:1797)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:945)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:1014)
at android.content.Intent.writeToParcel(Intent.java:11155)
at android.app.IActivityTaskManager$Stub$Proxy.startAppLockService(IActivityTaskManager.java:8468)
at android.app.Activity.startAppLockService(Activity.java:8950)
at android.app.Activity.performStart(Activity.java:8022)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3512)
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:2175)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7860)
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:1075)
Caused by: java.io.NotSerializableException: androidx.appcompat.widget.Toolbar
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.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:1845)
at android.os.Parcel.writeValue(Parcel.java:1797)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:945)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:1014)
at android.content.Intent.writeToParcel(Intent.java:11155)
at android.app.IActivityTaskManager$Stub$Proxy.startAppLockService(IActivityTaskManager.java:8468)
at android.app.Activity.startAppLockService(Activity.java:8950)
at android.app.Activity.performStart(Activity.java:8022)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3512)
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:2175)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7860)
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:1075)
Activity.java
public class BaseFragmentActivity extends AppCompatActivity implements Serializable, View.OnClickListener {
private static final String TAG = "BaseFragmentActivity";
private Toolbar mToolbar;
private ImageView tBtnSave, tBtnBack;
private TextView tTxtTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_fragment);
mToolbar = findViewById(R.id.toolbar);
tBtnSave = findViewById(R.id.toolbar_btn_save);
tBtnBack = findViewById(R.id.toolbarBtnBack);
tTxtTitle = findViewById(R.id.toolbar_title);
}
...
}
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.android.app"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
}
buildTypes {
debug {
debuggable true
buildConfigField "Boolean", "DEBUG_MODE", "true"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:support-annotations:28.0.0'
annotationProcessor 'com.android.support:support-annotations:28.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.palette:palette:1.0.0'
//External Animation Library
implementation 'com.airbnb.android:lottie:3.4.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
编辑并修复。
public class BaseFragmentActivity extends AppCompatActivity implements Serializable, View.OnClickListener {
// By using `transient` keyword to define view or class to say it's not serialized view or class.
private static final String TAG = "BaseFragmentActivity";
private transient Toolbar mToolbar;
private transient AppCompatImageView tBtnSave, tBtnBack;
private transient AppCompatTextView tTxtTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_fragment);
mToolbar = findViewById(R.id.toolbar);
tBtnSave = findViewById(R.id.toolbar_btn_save);
tBtnBack = findViewById(R.id.toolbarBtnBack);
tTxtTitle = findViewById(R.id.toolbar_title);
}
...
}
看起来你的代码中某处,你正在尝试将整个 Fragment
(看起来是 CustomViewFragment
)写入 parcel:
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.android.ui.fragment.CustomViewFragment)
要序列化,您的 class 及其所有成员都必须实现 Serializable
。因为 Fragment
的上下文是 Activity
(可能是 BaseFragmentActivity
的子 class),它也经历了序列化过程。但是 Fragment
和 Activity
都没有实现 Serializable
接口。
这是您的解决方案:
transient 是用于序列化的变量修饰符。在序列化时,如果我们不想在文件中保存特定变量的值,那么我们使用 transient 关键字。当 JVM 遇到 transient 关键字时,它会忽略变量的原始值并保存该变量数据类型的默认值。
所以,它很少使用来告诉你的编译器这个变量不是可序列化方法的一部分。
我得到了 Parcelable encountered IOException writing serializable object
,它是由 java.io.NotSerializableException: androidx.appcompat.widget.Toolbar
错误引起的,仅在 Android 版本 10 设备中。
我搜索了很多结果来解决这个问题,但我得到的每一个解决方案都告诉我在 inner class 中定义 implement serializable
和 sub inner class 我已经做到了,但是,我只在 Android 版本 10 设备中遇到这个错误。
如果我将使用 transient
这个关键字来定义视图或对象,那么这个错误将得到修复,但同样的错误会出现在另一个视图、适配器和 class.
Logcat
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.android.ui.fragment.CustomViewFragment)
at android.os.Parcel.writeSerializable(Parcel.java:1850)
at android.os.Parcel.writeValue(Parcel.java:1797)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:945)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:1014)
at android.content.Intent.writeToParcel(Intent.java:11155)
at android.app.IActivityTaskManager$Stub$Proxy.startAppLockService(IActivityTaskManager.java:8468)
at android.app.Activity.startAppLockService(Activity.java:8950)
at android.app.Activity.performStart(Activity.java:8022)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3512)
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:2175)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7860)
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:1075)
Caused by: java.io.NotSerializableException: androidx.appcompat.widget.Toolbar
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.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:1845)
at android.os.Parcel.writeValue(Parcel.java:1797)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:945)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1584)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:1014)
at android.content.Intent.writeToParcel(Intent.java:11155)
at android.app.IActivityTaskManager$Stub$Proxy.startAppLockService(IActivityTaskManager.java:8468)
at android.app.Activity.startAppLockService(Activity.java:8950)
at android.app.Activity.performStart(Activity.java:8022)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3512)
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:2175)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7860)
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:1075)
Activity.java
public class BaseFragmentActivity extends AppCompatActivity implements Serializable, View.OnClickListener {
private static final String TAG = "BaseFragmentActivity";
private Toolbar mToolbar;
private ImageView tBtnSave, tBtnBack;
private TextView tTxtTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_fragment);
mToolbar = findViewById(R.id.toolbar);
tBtnSave = findViewById(R.id.toolbar_btn_save);
tBtnBack = findViewById(R.id.toolbarBtnBack);
tTxtTitle = findViewById(R.id.toolbar_title);
}
...
}
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.android.app"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true
}
buildTypes {
debug {
debuggable true
buildConfigField "Boolean", "DEBUG_MODE", "true"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:support-annotations:28.0.0'
annotationProcessor 'com.android.support:support-annotations:28.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.palette:palette:1.0.0'
//External Animation Library
implementation 'com.airbnb.android:lottie:3.4.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
编辑并修复。
public class BaseFragmentActivity extends AppCompatActivity implements Serializable, View.OnClickListener {
// By using `transient` keyword to define view or class to say it's not serialized view or class.
private static final String TAG = "BaseFragmentActivity";
private transient Toolbar mToolbar;
private transient AppCompatImageView tBtnSave, tBtnBack;
private transient AppCompatTextView tTxtTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_fragment);
mToolbar = findViewById(R.id.toolbar);
tBtnSave = findViewById(R.id.toolbar_btn_save);
tBtnBack = findViewById(R.id.toolbarBtnBack);
tTxtTitle = findViewById(R.id.toolbar_title);
}
...
}
看起来你的代码中某处,你正在尝试将整个 Fragment
(看起来是 CustomViewFragment
)写入 parcel:
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.android.ui.fragment.CustomViewFragment)
要序列化,您的 class 及其所有成员都必须实现 Serializable
。因为 Fragment
的上下文是 Activity
(可能是 BaseFragmentActivity
的子 class),它也经历了序列化过程。但是 Fragment
和 Activity
都没有实现 Serializable
接口。
这是您的解决方案:
transient 是用于序列化的变量修饰符。在序列化时,如果我们不想在文件中保存特定变量的值,那么我们使用 transient 关键字。当 JVM 遇到 transient 关键字时,它会忽略变量的原始值并保存该变量数据类型的默认值。
所以,它很少使用来告诉你的编译器这个变量不是可序列化方法的一部分。