У меня есть приложение для Android, чьи отладочные сборки отлично работают. Его выпуск сборка, однако, который включает в себя запутывание с ProGuard (конфигурация показана ниже), не работает, и всегда падает на старте со следующим журналом:SuperNotCalledException после обфускации с помощью Proguard
01-26 15:33:34.048 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.alxdroiddev.cameragear, PID: 6551
co: Fragment FragmentIntro{13af572c id=0x7f100177 android:switcher:2131755383:0} did not call through to super.onAttach()
at android.support.v4.app.FragmentManagerImpl.a(SourceFile:1232)
at android.support.v4.app.FragmentManagerImpl.v(SourceFile:2323)
at android.support.v4.app.FragmentManagerImpl.a(SourceFile:2136)
at android.support.v4.app.FragmentManagerImpl.b(SourceFile:2092)
at android.support.v4.app.FragmentManagerImpl.b(SourceFile:1969)
at bu.commitNowAllowingStateLoss(SourceFile:620)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(SourceFile:143)
at android.support.v4.view.ViewPager.populate(SourceFile:1268)
at android.support.v4.view.ViewPager.populate(SourceFile:1116)
at android.support.v4.view.ViewPager.onMeasure(SourceFile:1642)
at android.view.View.measure(View.java:17430)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.support.v7.widget.ContentFrameLayout.onMeasure(SourceFile:139)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
at android.view.View.measure(View.java:17430)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Я пытался добавить необходимые звонки (переопределяя onAttach()
в дефектный фрагмент), но это не имело никакого значения. Этот фрагмент находится в коде ниже и используется с библиотекой AppIntro. Это код FragmentIntro.java
:
public class FragmentIntro extends Fragment implements ISlideBackgroundColorHolder { /* Static stuff */ private static final String ARG_LAYOUT_TITLE_ID = "titleId"; private static final String ARG_LAYOUT_MESSAGE_ID = "messageId"; private static final String ARG_LAYOUT_DRAWABLE_ID = "drawableId"; private static final String ARG_LAYOUT_COLOR_ID = "colorId"; //private static final int layoutResId = R.layout.intro_fragment; /* Private instance variables */ private int titleRedId, messageResId, drawableId, colorResId, colorCode; private RelativeLayout mainLayout; public static FragmentIntro newInstance(@StringRes int titleId, @StringRes int messageId, @DrawableRes int drawableId, @ColorRes int colorId) { FragmentIntro fragSlide = new FragmentIntro(); Bundle args = new Bundle(); args.putInt(ARG_LAYOUT_TITLE_ID, titleId); args.putInt(ARG_LAYOUT_MESSAGE_ID , messageId); args.putInt(ARG_LAYOUT_DRAWABLE_ID , drawableId); args.putInt(ARG_LAYOUT_COLOR_ID, colorId); fragSlide.setArguments(args); return fragSlide; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { this.titleRedId = getArguments().getInt(ARG_LAYOUT_TITLE_ID); this.messageResId = getArguments().getInt(ARG_LAYOUT_MESSAGE_ID); this.drawableId = getArguments().getInt(ARG_LAYOUT_DRAWABLE_ID); this.colorResId = getArguments().getInt(ARG_LAYOUT_COLOR_ID); } } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //super.onCreateView(inflater, container, savedInstanceState); //if (container == null) return null; View view = inflater.inflate(R.layout.intro_fragment, container, false); Utils.globalAppContext = getContext().getApplicationContext(); colorCode = ContextCompat.getColor(getContext().getApplicationContext(), colorResId); mainLayout = (RelativeLayout) view.findViewById(R.id.introLayout); mainLayout.setBackgroundColor(colorCode); ((TextView) view.findViewById(R.id.textViewIntroTitle)).setText(titleRedId); ((TextView) view.findViewById(R.id.textViewIntroMessage)).setText(messageResId); ((ImageView) view.findViewById(R.id.imageViewIntro)).setImageDrawable(Utils.getDrawableFromResource(drawableId)); return view; } @Override public void onSaveInstanceState(Bundle outState) { outState.putInt(ARG_LAYOUT_TITLE_ID, titleRedId); outState.putInt(ARG_LAYOUT_MESSAGE_ID, messageResId); outState.putInt(ARG_LAYOUT_DRAWABLE_ID, drawableId); outState.putInt(ARG_LAYOUT_COLOR_ID, colorResId); super.onSaveInstanceState(outState); } @Keep @TargetApi(23) @Override public void onAttach(Context context) { super.onAttach(context); } @Keep @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onPause() { super.onPause(); } @Override public void onResume() { super.onResume(); } @Override public void onStart() { super.onStart(); } @Override public void onStop() { super.onStop(); } // Implementation of ISlideBackgroundColorHolder @Override public int getDefaultBackgroundColor() { return colorCode; } @Override public void setBackgroundColor(@ColorInt int backgroundColor) { mainLayout.setBackgroundColor(backgroundColor); } }
Файл ProGuard конфигурации Я использую это (и только это):
#################################################################### GENERAL OPTIONS -optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -verbose -dontpreverify -repackageclasses '' -allowaccessmodification -mergeinterfacesaggressively -overloadaggressively -keepattributes *Annotation*,Signature,EnclosingMethod,InnerClasses -assumenosideeffects class com.alxdroiddev.cameragear.FragmentQueryRunner { *; } -assumenosideeffects class com.alxdroiddev.cameragear.FragmentCards { *; } -assumenosideeffects class com.alxdroiddev.cameragear.db.InitialSampleData { *; } # Required for Firebase Database (Models and POJOs) -keepclassmembers class com.alxdroiddev.cameragear.models.** { *; } #################################################################### REMOVE LOGGING -assumenosideeffects class android.util.Log { public static *** e(...); public static *** w(...); public static *** wtf(...); public static *** d(...); public static *** v(...); public static *** i(...); } -assumenosideeffects class com.alxdroiddev.utils.CLog { *; } #################################################################### IMAGECROPPER -keepnames class com.theartofdev.edmodo.cropper.** { *; } #################################################################### APPINTRO -keep class com.github.paolorotolo.** {*;} -keep public class com.alxdroiddev.cameragear.utils.FragmentIntro -keepclassmembers public class com.alxdroiddev.cameragear.utils.FragmentIntro {*;} -keep public class com.alxdroiddev.cameragear.ActivityIntro -keepclassmembers public class com.alxdroiddev.cameragear.ActivityIntro {*;} #################################################################### METADATA-EXTRACTOR -keep class com.drew.imaging.** { *; } -keep class com.drew.metadata.** { *; } -keep class com.drew.lang.** { *; } #################################################################### MISC STUFF -keep class * extends java.util.ListResourceBundle { protected java.lang.Object[][] getContents(); } # Needed for Parcelable/SafeParcelable Creators to not get stripped -keepnames class * implements android.os.Parcelable { public static final ** CREATOR; } -keepclassmembers class * implements android.os.Parcelable { static ** CREATOR; } # Needed when building against pre-Marshmallow SDK. -dontwarn android.security.NetworkSecurityPolicy -keep class android.support.customtabs.** { *; } -dontwarn android.support.customtabs.** -keep class com.google.android.gms.** { *; } -dontwarn com.google.android.gms.** #################################################################### IN-APP BILLING -keep public interface com.android.vending.licensing.ILicensingService -keep public class com.google.vending.licensing.ILicensingService -keep public class com.android.vending.licensing.ILicensingService #################################################################### KEEP ANDROID SUPPORT V7 AND DESIGN -dontwarn android.support.design.** -keep class android.support.design.** { *; } -keep interface android.support.design.** { *; } -keep public class android.support.design.R$** { *; } -keep public class android.support.v7.widget.** { *; } -keep public class android.support.v7.internal.widget.** { *; } -keep public class android.support.v7.internal.view.menu.** { *; } -keep public class * extends android.support.v4.view.ActionProvider { public (android.content.Context); } -keep public class android.support.v14.preference.** { *; } -keep public class android.support.v7.app.** { *; } -keep public class android.support.v7.preference.** { *; } -keep public class android.support.v4.app.** { *; } -dontwarn android.support.** -keep interface android.support.v4.** { *; } -keep interface android.support.v7.** { *; } -keep interface android.support.v13.** {*; } -keep interface android.support.v14.** {*; } #################################################################### ORG.APACHE.HTTP -keep class org.apache.http.** { *; } -keep interface org.apache.http.** -dontwarn org.apache.** #################################################################### GOOGLE PLAY SERVICES LIB - ADS -keep public class com.google.android.gms.** { public *; } #-keep class com.google.android.gms.** # For Google Play Services -keep public class com.google.android.gms.ads.**{ public *; } #################################################################### FIREBASE -keep public class com.google.firebase.** { *; } -keep public class com.google.firebase.analytics.** { *; } -keep public class com.google.firebase.provider.** { *; } -keep public class com.google.firebase.auth.** { *; } -keep interface com.google.firebase.** {*; } -keep class com.firebase.** { *; } #################################################################### SUGGESTED OPTIMIZATIONS BY GOOGLE # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native -keepclasseswithmembernames class * { native ; } # keep setters in Views so that animations can still work. # see http://proguard.sourceforge.net/manual/examples.html#beans -keepclassmembers public class * extends android.view.View { void set*(***); *** get*(); } # We want to keep methods in Activity that could be used in the XML attribute onClick -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keepclassmembers class **.R$* { public static ; } # Understand the @Keep support annotation. -keep class android.support.annotation.Keep -keep @android.support.annotation.Keep class * {*;} -keepclasseswithmembers class * { @android.support.annotation.Keep ; } -keepclasseswithmembers class * { @android.support.annotation.Keep ; } -keepclasseswithmembers class * { @android.support.annotation.Keep (...); }
Я потерял, сколько часов я потратил, пытаясь для решения этой проблемы, особенно потому, что все работает в режиме отладки и без жалобы на super.onAttach()
. Это происходит только после обфускации с помощью приведенной выше конфигурации.
Большое спасибо за внимание, и любая помощь приветствуется.
С уважением.
Эти строки были неудачной попыткой избавиться от ошибки. Поскольку сообщение журнала жаловалось на их отсутствие, я просто помещаю их туда (наряду с другими переопределениями, которые просто называют их супер методы). Я полагаю, что они не причинят вреда. – AlxDroidDev