AndroidX:Parcelable 遇到 IOException,仅在 Android 版本 10 设备中写入可序列化对象 [英] AndroidX : Parcelable encountered IOException writing serializable object only in Android version 10 devices
问题描述
我得到 Parcelable 遇到 IOException 写入可序列化对象
并且它是由 java.io.NotSerializableException: androidx.appcompat.widget.Toolbar
错误引起的,仅在 Android 版本 10 设备中.
I got Parcelable encountered IOException writing serializable object
and it caused by java.io.NotSerializableException: androidx.appcompat.widget.Toolbar
error only in Android Version 10 devices.
我搜索了很多结果来解决这个问题,但我得到的每个解决方案都告诉在 内部类 和 sub 中定义 implement serializable
内部类,我已经做到了,但我只在 Android 10 版设备中遇到了这个错误.
I've searched many results for getting solutions to this problem but every solution I got, was telling to define implement serializable
in both inner class and sub inner class and I've done it, still, I got this error only in Android version 10 devices.
如果我将使用 transient
这个关键字来定义视图或对象,那么这个错误将会修复,但同样的错误会伴随另一个视图、适配器和类.
If I will use transient
this keyword to define View or object then this error will fix but this same error comes with another view, adapter, and 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);
}
...
}
推荐答案
这是你的解决方案:
transient 是序列化中使用的变量修饰符.在序列化的时候,如果我们不想在文件中保存某个特定变量的值,那么我们使用transient关键字.当JVM遇到transient关键字时,它会忽略变量的原始值并保存该变量数据类型的默认值.
transient is a variables modifier used in serialization. At the time of serialization, if we don't want to save value of a particular variable in a file, then we use transient keyword. When JVM comes across transient keyword, it ignores original value of the variable and save default value of that variable data type.
因此,它使用了非常罕见的方式来告诉您的编译器该变量不是可序列化数学的一部分.
So, it uses quite rare in order to say to your compiler that this variable is not a part of serializable mathod.
这篇关于AndroidX:Parcelable 遇到 IOException,仅在 Android 版本 10 设备中写入可序列化对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!