Android Proguard 崩溃,错误无法启动 activity ComponentInfo{com.xx.xxx/com.xx.xxx.activity.MainActivity}:

Android Proguard Crash with error Unable to start activity ComponentInfo{com.xx.xxx/com.xx.xxx.activity.MainActivity}:

我正在我的 Android 应用程序中实施 Proguard。当我通过 Intent 成功登录后启动 MainActivity 时,它的显示应用程序已停止。如何在 Android 应用程序中无错误地实施 Proguard?

我的logcat如下:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xx.xxx/com.xx.xxx.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2785)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1524)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6239)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794) Caused by: 

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference   
at com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx.getBottomNavigationItemViews(SourceFile:569)
at com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx.a(SourceFile:341)
at com.xx.xxx.activity.MainActivity.onCreate(SourceFile:62)
at android.app.Activity.performCreate(Activity.java:6875)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2677)
... 9 more

我的Proguard规则如下:

Progaurd.pro

-keepclassmembers class fqcn.of.javascript.interface.for.webview {public *;}
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
 // Retrofit 2.X
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepclasseswithmembers class * {
 @retrofit2.http.* <methods>;
}

//---------------Begin: proguard configuration for Gson  ----------
-keepattributes Signature
-keepattributes *Annotation*
-dontwarn sun.misc.**
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
//---------------End: proguard configuration for Gson  ----------

-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-keep class com.google.firebase.quickstart.database.viewholder.** {*;}
-keepclassmembers class com.google.firebase.quickstart.database.models.** {*;}
-keep public class com.google.** {*;}

// We only want obfuscation
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keep class com.xx.xxx.activity.* {*;}
-keep class com.xx.xxx.activity.** {*;}
-keep class com.xx.xxx.activity.*** {*;}
-keep class com.xx.xxx.activity.**** {*;}
-keep class com.xx.xxx.activity.***** {*;}
-keep class com.xx.xxx.*** { *; }
-keep class com.xx.xxx.**** { *; }
-keep class com.xx.xxx.***** { *; }

// Sdk
-keep public interface com.xx.xxx.* { *; }
-keep public interface com.xx.xxx.** { *; }
-keep public interface com.xx.xxx.*** { *; }
-keep public interface com.xx.xxx.**** { *; }
-keep public interface com.xx.xxx.***** { *; }

-keep public class com.xx.xxx.* { *; }
-keep public class com.xx.xxx.** { *; }
-keep public class com.xx.xxx.*** { *; }
-keep public class com.xx.xxx.**** { *; }
-keep public class com.xx.xxx.***** { *; }

-dontwarn java.awt.**
-keep public class com.xx.xxx.model.*** { *; }
-keepattributes *Annotation*

// Appcompat and support
-keep interface android.support.v7.** { *; }
-keep class android.support.v7.** { *; }
-keep interface android.support.v4.** { *; }
-keep class android.support.v4.** { *; }
-dontwarn android.app.Notification

//PDFView in your layout
-keep class com.shockwave.**

// restrict obfuscation of classes extended from Activity
-keep public class * extends android.support.v7.app.AppCompatActivity
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgent
-keep public class * extends android.preference.Preference
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.support.v4.app.DialogFragment
-keep public class * extends com.actionbarsherlock.app.SherlockListFragment
-keep public class * extends com.actionbarsherlock.app.SherlockFragment
-keep public class * extends com.actionbarsherlock.app.SherlockFragmentActivity
-keep public class * extends android.app.Fragment
-keep public class com.android.vending.licensing.ILicensingService

// For native methods
-keepclasseswithmembernames class * { native <methods>;}
-keepclassmembers class * implements android.os.Parcelable {static **CREATOR;}

// restrict obfuscation of data members which has parcelable implemention
// Hide warnings about references to newer platforms in the library
-dontwarn android.support.v7.**

// don't process support library
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

AndroidMenifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xx.xxx">

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:name=".xxxxx"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"

    android:largeHeap="true"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".activity.MainActivity"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme" />
    <activity
        android:name=".activity.Login"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.SignUp"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.ForgotPassword"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.ResetPassword"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.ViewProfile"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.ChangePasswordUser"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.Chat"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.ChatWithOutReply"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.SubCategory"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.WebActivity"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.ChatSingleItem"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.homeSubActivity.ExamPreparation"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.Splash"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name=".push_notification.service.MyFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service android:name=".push_notification.service.MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@mipmap/ic_launcher" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />
    <meta-data
        android:name="firebase_messaging_auto_init_enabled"
        android:value="false" />
    <meta-data
        android:name="firebase_analytics_collection_enabled"
        android:value="false" />

    <activity
        android:name=".activity.chat.liveClassSubActivity.VideoListing"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.liveClassSubActivity.VideoViews"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="stateHidden"
        android:theme="@style/FullScreenTheme" />
    <activity
        android:name=".activity.chat.liveClassSubActivity.test.TestActivity"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.liveClassSubActivity.VideoAssessmentTest"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.PaymentGateway"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.liveClassSubActivity.test.TestListActivity"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.liveClassSubActivity.test.TestWebView"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.liveClassSubActivity.DoubtsActivity"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.PdfView"
        android:label="@string/app_"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.homeSubActivity.AskQuestions"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.OTPRegistration"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.careerwill.careerwillapp.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

    <activity
        android:name=".activity.WebView"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.homeSubActivity.ImageListing"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.homeSubActivity.PdfListing"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.homeSubActivity.WeeklyLink"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
    <activity
        android:name=".activity.chat.homeSubActivity.LatestUpdateCurrentAffair"
        android:screenOrientation="portrait"
        android:theme="@style/FullScreenTheme"
        android:windowSoftInputMode="stateAlwaysHidden" />
  </application>

</manifest>

build.gradle(模块:app)

apply plugin: 'com.android.application'
android {
    compileSdkVersion 27
    defaultConfig {
    applicationId "com.xx.xxx"
    minSdkVersion 17
    targetSdkVersion 27
    versionCode 8
    versionName "1.7"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    debug {
        minifyEnabled true
        useProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    release {
        minifyEnabled true
        useProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }
}
dependencies {
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:exifinterface:27.1.1'
    implementation 'com.android.support:customtabs:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    implementation 'com.android.support:cardview-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.github.bumptech.glide:glide:4.7.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
    implementation 'com.google.code.gson:gson:2.8.2'
    implementation 'com.google.firebase:firebase-core:15.0.2'
    implementation 'com.google.firebase:firebase-messaging:15.0.2'
    implementation 'me.leolin:ShortcutBadger:1.1.21@aar'
    implementation 'com.github.ittianyu:BottomNavigationViewEx:1.2.4'
    implementation 'com.android.support:support-v4:27.1.1'
    implementation 'com.android.support:customtabs:27.1.1'
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:8.0.1'
    implementation 'com.scottyab:rootbeer-lib:0.0.4'

    annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    apply plugin: 'com.google.gms.google-services'
}

我找到了答案,我错过了 BottomNavigationViewEx 库的 Proguard 规则。这是:

-keep public class android.support.design.widget.BottomNavigationView { *; }
-keep public class android.support.design.internal.BottomNavigationMenuView { *; }
-keep public class android.support.design.internal.BottomNavigationPresenter { *; }
-keep public class android.support.design.internal.BottomNavigationItemView { *; }

正如@kunwar 所说。这与我的情况相同。

对于 androidX progaurd

-keep public class com.google.android.material.bottomnavigation.BottomNavigationView { *; }
-keep public class com.google.android.material.bottomnavigation.BottomNavigationMenuView { *; }
-keep public class com.google.android.material.bottomnavigation.BottomNavigationPresenter { *; }
-keep public class com.google.android.material.bottomnavigation.BottomNavigationItemView { *; }

来自: https://github.com/ittianyu/BottomNavigationViewEx