2019-09-1021:56:10.3273667-3667/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.proguardbugtest, PID: 3667 java.lang.VerifyError: Verifier rejected class com.example.proguardbugtest.MainActivity: void com.example.proguardbugtest.MainActivity.onCreate(android.os.Bundle) failed to verify: void com.example.proguardbugtest.MainActivity.onCreate(android.os.Bundle): [0x3D] cannot access instance field java.lang.String com.example.a.a.a from objectoftype Unresolved Reference: com.example.base.Account (declaration of 'com.example.proguardbugtest.MainActivity' appears in /data/app/com.example.proguardbugtest-5HQbNJwMRzeKoIg1ZzDmjA==/base.apk) at java.lang.Class.newInstance(Native Method) at android.app.Instrumentation.newActivity(Instrumentation.java:1173) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2708) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
2019-09-1022:56:02.4566516-6516/com.example.proguardbugtest E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.proguardbugtest, PID: 6516 java.lang.InternalError at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:509) at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:354) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1165) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346) at android.os.Parcel.writeSerializable(Parcel.java:1521) at android.os.Parcel.writeValue(Parcel.java:1474) at android.os.Parcel.writeArrayMapInternal(Parcel.java:723) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1408) at android.os.Bundle.writeToParcel(Bundle.java:1133) at android.os.Parcel.writeBundle(Parcel.java:763) at android.content.Intent.writeToParcel(Intent.java:8655) at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3052) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1518) at android.app.Activity.startActivityForResult(Activity.java:4224) at android.app.Activity.startActivityForResult(Activity.java:4183) at android.app.Activity.startActivity(Activity.java:4507) at android.app.Activity.startActivity(Activity.java:4475) at com.example.proguardbugtest.MainActivity$1.onClick(Unknown Source) at android.view.View.performClick(View.java:5610) at android.view.View$PerformClick.run(View.java:22265) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
/* * Even if fields == localFields, we cannot simply return localFields * here. In previous implementations of serialization, * ObjectStreamField.getType() returned Object.class if the * ObjectStreamField represented a non-primitive field and belonged to * a non-local class descriptor. To preserve this (questionable) * behavior, the ObjectStreamField instances returned by matchFields * cannot report non-primitive types other than Object.class; hence * localFields cannot be returned directly. */
ObjectStreamField[] matches = newObjectStreamField[fields.length]; for (inti=0; i < fields.length; i++) { ObjectStreamFieldf= fields[i], m = null; for (intj=0; j < localFields.length; j++) { ObjectStreamFieldlf= localFields[j]; if (f.getName().equals(lf.getName())) { if ((f.isPrimitive() || lf.isPrimitive()) && f.getTypeCode() != lf.getTypeCode()) { thrownewInvalidClassException(localDesc.name, "incompatible types for field " + f.getName()); } if (lf.getField() != null) { m = newObjectStreamField( lf.getField(), lf.isUnshared(), false); } else { m = newObjectStreamField( lf.getName(), lf.getSignature(), lf.isUnshared()); } } } if (m == null) { m = newObjectStreamField( f.getName(), f.getSignature(), false); } m.setOffset(f.getOffset()); matches[i] = m; } return matches; }
// ... // Android-changed: We can have fields with a same name and a different type. if (f.getName().equals(lf.getName()) && f.getSignature().equals(lf.getSignature())) { if (lf.getField() != null) { // ...
继续搜索,发现这篇帖子,有人反馈了这个问题,作者表示:我并不太想给JRE的错误实现擦屁股,在代码里硬编码绕过这个问题(I’m not really eager to hard-code a workaround for what looks like a bug in the JRE implementation of serialization, but I’ll consider it.)。