过去3天我一直在解决这个问题.
我的应用程序已经完成,在一些设备和模拟器上进行了测试,并准备发布…或者我认为.在导出和签名之后(顺便说一句,我使用带ADT的Eclipse),它会在任何设备或模拟器中停止工作.我认为问题在于我的ProGuard配置,因为如果我在project.properties中禁用ProGuard,它在导出后会完美运行.
这是我的project.properties:
# Project target. target=android-23 android.library.reference.1=..\\google-play-services_lib android.library.reference.2=..\\android-support-design proguard.config=proguard.cfg
(如果我jusst评论上面的proguard.config =行,那么导出后一切正常)
proguard.cfg:
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -dontpreverify -verbose -dontwarn com.google.android.gms.** -dontwarn android.support.v4.app.** -dontwarn android.support.design.internal.** -allowaccessmodification -mergeinterfacesaggressively -overloadaggressively -optimizations !code/simplification/arithmetic -keepattributes *Annotation* -keep public class * extends android.app.Fragment -keep public class * extends android.support.v4.app.Fragment -keep public class * extends android.support.v4.app.FragmentPagerAdapter -keep public class * extends android.app.Fragment -keep public class * extends android.widget.** -keep public class * extends android.view.View -keep class * extends android.support.v7.** -dontwarn android.support.v4.** -keep class android.support.v4.** { *; } -dontwarn android.support.v7.** -keep class android.support.v7.internal.** { *; } -keep interface android.support.internal.v7.** { *; } -keep class com.google.android.gms.** # For Google Play Services -keep public class com.google.android.gms.ads.**{ public *; } -keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { public static final *** NULL; } -keep class android.support.** -keepnames class * implements android.os.Parcelable -keepclassmembers class * implements android.os.Parcelable { public static final *** CREATOR; } -keep @interface android.support.annotation.Keep -keep @android.support.annotation.Keep class * -keepclasseswithmembers class * { @android.support.annotation.Keep <fields>; } -keepclasseswithmembers class * { @android.support.annotation.Keep <methods>; } -keep @interface com.google.android.gms.common.annotation.KeepName -keepnames @com.google.android.gms.common.annotation.KeepName class * -keepclassmembernames class * { @com.google.android.gms.common.annotation.KeepName *; } -keep @interface com.google.android.gms.common.util.DynamiteApi -keep public @com.google.android.gms.common.util.DynamiteApi class * { public <fields>; public <methods>; } # Other required classes for Google Play Services # Read more at http://developer.android.com/google/play-services/setup.html -keep class * extends java.util.ListResourceBundle { protected Object[][] getContents(); } # Needed when building against pre-Marshmallow SDK. -dontwarn android.security.NetworkSecurityPolicy # Keep Metadata about included modules. -keep public class com.google.android.gms.dynamite.descriptors.** { public <fields>; } # Keep the implementation of the flags api for google-play-services-flags -keep public class com.google.android.gms.flags.impl.FlagProviderImpl { public <fields>; public <methods>; } -keep class org.apache.http.** -keep interface org.apache.http.** -dontwarn org.apache.** -keep public class android.net.http.SslError -keep public class android.webkit.WebViewClient -dontwarn android.webkit.WebView -dontwarn android.net.http.SslError -dontwarn android.webkit.WebViewClient -assumenosideeffects class android.util.Log { public static *** e(...); public static *** w(...); public static *** wtf(...); public static *** d(...); public static *** v(...); public static *** i(...); }
最后,当我在真实设备上运行我的应用程序时,我得到的错误日志:
06-08 21:19:23.448: E/AndroidRuntime(12411): FATAL EXCEPTION: main 06-08 21:19:23.448: E/AndroidRuntime(12411): Process: com.alxdroiddev.cchecker,PID: 12411 06-08 21:19:23.448: E/AndroidRuntime(12411): android.view.InflateException: Binary XML file line #12: Error inflating class Button 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.LayoutInflater.inflate(LayoutInflater.java:511) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.LayoutInflater.inflate(LayoutInflater.java:415) 06-08 21:19:23.448: E/AndroidRuntime(12411): at com.alxdroiddev.cchecker.LinksFragment.onCreateView(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.Fragment.performCreateView(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.BackStackRecord.run(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.FragmentManagerImpl.execPendingActions(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.app.FragmentPagerAdapter.finishUpdate(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.view.ViewPager.populate(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.view.ViewPager.setCurrentItemInternal(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.view.ViewPager.setCurrentItemInternal(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.view.ViewPager.setCurrentItem(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.a(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.design.widget.TabLayout.a(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.design.widget.TabLayout$Tab.a(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.design.widget.TabLayout$TabView.performClick(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.View$PerformClick.run(View.java:20916) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.os.Handler.handleCallback(Handler.java:739) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.os.Handler.dispatchMessage(Handler.java:95) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.os.Looper.loop(Looper.java:145) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.app.ActivityThread.main(ActivityThread.java:5944) 06-08 21:19:23.448: E/AndroidRuntime(12411): at java.lang.reflect.Method.invoke(Native Method) 06-08 21:19:23.448: E/AndroidRuntime(12411): at java.lang.reflect.Method.invoke(Method.java:372) 06-08 21:19:23.448: E/AndroidRuntime(12411): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 06-08 21:19:23.448: E/AndroidRuntime(12411): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 06-08 21:19:23.448: E/AndroidRuntime(12411): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.AppCompatBackgroundHelper.b(android.content.res.ColorStateList)' on a null object reference 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v7.widget.AppCompatButton.setBackgroundDrawable(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.View.setBackground(View.java:17237) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.View.<init>(View.java:4335) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.widget.TextView.<init>(TextView.java:1002) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.widget.Button.<init>(Button.java:115) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.widget.Button.<init>(Button.java:108) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v7.widget.AppCompatButton.<init>(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v7.widget.AppCompatButton.<init>(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(Unknown Source) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:181) 06-08 21:19:23.448: E/AndroidRuntime(12411): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732) 06-08 21:19:23.448: E/AndroidRuntime(12411): ... 28 more
我的应用有一个TabLayout和4个标签的活动.第一个选项卡始终成功打开.如果我切换到另一个选项卡(更改片段),我会得到上面的错误.即使切换到的片段中没有Button视图,我也会得到相同的错误.
在此先感谢您的帮助.过去3天我一直在努力解决这个问题.
解决方法
我解决了问题.
这是我最终得到的最终proguard.cfg文件,它编译了几个优化并使我的应用程序顺利运行:
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -verbose -dontpreverify -allowaccessmodification -mergeinterfacesaggressively -overloadaggressively -keepattributes *Annotation* #################################################################### 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 <init>(android.content.Context); } -keep interface android.support.v4.** { *; } -keep interface android.support.v7.** { *; } -keep class android.support.** { *; } #################################################################### REMOVE WARNINGS -dontwarn android.support.design.internal.** -dontwarn com.google.android.gms.** -dontwarn android.support.v4.** #################################################################### 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(...); } #################################################################### ORG.APACHE.HTTP -keep class org.apache.http.** -keep interface org.apache.http.** -dontwarn org.apache.** #################################################################### WEVVIEW -keep public class android.net.http.SslError -keep public class android.webkit.WebViewClient -dontwarn android.webkit.WebView -dontwarn android.net.http.SslError -dontwarn android.webkit.WebViewClient #################################################################### 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 *; } #################################################################### GOOGLE PLAY SERVICES LIB -keep class * extends java.util.ListResourceBundle { protected java.lang.Object[][] getContents(); } # Keep SafeParcelable value,needed for reflection. This is required to support backwards # compatibility of some classes. -keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { public static final *** NULL; } # Keep the names of classes/members we need for client functionality. -keep @interface com.google.android.gms.common.annotation.KeepName -keepnames @com.google.android.gms.common.annotation.KeepName class * -keepclassmembernames class * { @com.google.android.gms.common.annotation.KeepName *; } # Needed for Parcelable/SafeParcelable Creators to not get stripped -keepnames class * implements android.os.Parcelable { public static final ** CREATOR; } # Needed when building against pre-Marshmallow SDK. -dontwarn android.security.NetworkSecurityPolicy # Keep Metadata about included modules. -keep public class com.google.android.gms.dynamite.descriptors.** { public <fields>; } # Keep the implementation of the flags api for google-play-services-flags -keep public class com.google.android.gms.flags.impl.FlagProviderImpl { public <fields>; public <methods>; }
我将这个放在这里作为我自己问题的答案,因为上面的配置可能会帮助那些也失去时间并且使用ProGuard睡觉的人.
https://github.com/krschultz/android-proguard-snippets/tree/master/libraries
上面的页面提供了几个特定于库的ProGuard配置的集合,包括android.support.v7和android.support.design.