简体   繁体   中英

App crashes when select Release mode but in debug mode works perfectly

I want to reduce size of my application therefore I am using minifyEnabled true in release mode but due to this application crashes. Following is my

build.gradle

 buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // replace with the current version of the Android plugin
        classpath 'com.android.tools.build:gradle:1.1.0'
        // the latest version of the android-apt plugin
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
    }

    apply plugin: 'com.android.application'
    apply plugin: 'com.neenbedankt.android-apt'

    apt {
    arguments {
        androidManifestFile variant.outputs[0].processResources.manifestFile
        resourcePackageName android.defaultConfig.applicationId
     }
     }

     android {
     compileSdkVersion 21
     buildToolsVersion "21.1.2"

     defaultConfig {
        applicationId "com.iifl.news.codereduce"
        minSdkVersion 10
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {

        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'

    }
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'

    }
    }

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:21.+'
    compile 'com.android.support:appcompat-v7:22.0.0'
    compile 'com.jakewharton:butterknife:5.0.+'
    compile 'com.jakewharton.timber:timber:2.2.+'
    compile 'com.squareup.dagger:dagger:1.2.+'
    provided 'com.squareup.dagger:dagger-compiler:1.2.+'
    apt 'com.squareup.dagger:dagger-compiler:1.2.2'


    compile 'com.squareup.okhttp:okhttp:2.0.0'
    compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
    compile 'com.squareup.retrofit:retrofit:1.6.1'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.4.+'
    compile 'com.fasterxml.jackson.core:jackson-core:2.4.+'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.4.+'
    compile 'com.github.satyan:sugar:1.3'
    compile 'com.pnikosis:materialish-progress:1.2'
    compile 'com.android.support:cardview-v7:21.0.3'
    compile 'com.google.android.gms:play-services-analytics:7.0.0'

    compile files('libs/volley.jar')
   }

I had added proguard-rules.pro. If I remove this then it gives me multiple warning.

-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class okhttp.** { *; }
-dontwarn okhttp.**


-keep class retrofit.** { *; }
-dontwarn retrofit.**

-keep class okio.** { *; }
-dontwarn okio.**

-keep class dagger.** { *; }
-dontwarn dagger.**
-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
-dontwarn okio.**
-dontwarn    com.squareup.okhttp.internal.huc.JavaApiConverter$CacheHttpURLConnection
-dontwarn com.squareup.okhttp.internal.huc.HttpURLConnectionImpl

My Manifest is like:

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


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<application
    android:name=".app.IIFLApplication"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".activities.SplashActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <activity
        android:name=".activities.BaseActivity"
        android:label="@string/title_activity_iiflbase"
        android:screenOrientation="portrait" >
    </activity>
</application>

</manifest>

My IIFLApplication class is like:

    public class IIFLApplication extends Application {

    private ObjectGraph applicationGraph;
    private Tracker tracker;

    private static final String PROPERTY_ID = "UA-61984632-2";

    public static int GENERAL_TRACKER = 0;

    public enum TrackerName {
        APP_TRACKER, GLOBAL_TRACKER, ECOMMERCE_TRACKER,
    }

    public HashMap mTrackers = new HashMap();

    @Override
    public void onCreate() {
        super.onCreate();
        /*if (BuildConfig.DEBUG) {
            Timber.plant(new DebugTree());
        } else {
            //Timber.plant(new CrashlyticsTree());
        }*/

        //create object graph
        applicationGraph = ObjectGraph.create(getModules().toArray());
        applicationGraph.inject(this);
    }

    private List<Object> getModules() {
        return Arrays.<Object>asList(new AppModule(this));
    }

    public ObjectGraph getApplicationGraph() {
        return this.applicationGraph;
    }

    /**
     * A tree which logs important information for crash reporting.
     */
    private static class CrashlyticsTree extends Timber.HollowTree {
        @Override
        public void v(String message, Object... args) {
            logMessage(message, args);
        }

        @Override
        public void v(Throwable t, String message, Object... args) {
            logMessage(message, args);
            // NOTE: We are explicitly not sending the exception to Crashlytics here.
        }

        @Override
        public void i(String message, Object... args) {
            logMessage(message, args);
        }

        @Override
        public void i(Throwable t, String message, Object... args) {
            logMessage(message, args);
            // NOTE: We are explicitly not sending the exception to Crashlytics here.
        }

        @Override
        public void w(String message, Object... args) {
            logMessage("WARN: " + message, args);
        }

        @Override
        public void w(Throwable t, String message, Object... args) {
            logMessage("WARN: " + message, args);
            // NOTE: We are explicitly not sending the exception to Crashlytics here.
        }

        @Override
        public void e(String message, Object... args) {
            logMessage("ERROR: " + message, args);
        }

        @Override
        public void e(Throwable t, String message, Object... args) {
            logMessage("ERROR: " + message, args);
            //Crashlytics.logException(t);
        }

        private void logMessage(String message, Object... args) {
            //Crashlytics.log(String.format(message, args));
        }
    }



    public synchronized Tracker getTracker(TrackerName appTracker) {
        if (!mTrackers.containsKey(appTracker)) {
            GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
            Tracker t = (appTracker == TrackerName.APP_TRACKER) ? analytics.newTracker(PROPERTY_ID) : (appTracker == TrackerName.GLOBAL_TRACKER) ? analytics.newTracker(R.xml.global_tracker) : analytics.newTracker(R.xml.ecommerce_tracker);
            mTrackers.put(appTracker, t);
        }
        return (Tracker) mTrackers.get(appTracker);
    }
   }

I think is due to proguard. But I am not getting what wrong I am doing. Any suugestion will be appreciated. Thanks in advance

Folllowing is my logcat: Application crashesh instantly after run.

05-22 15:15:43.067    3158-3158/com.iifl.news.codereduce E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.iifl.news.codereduce, PID: 3158
java.lang.RuntimeException: Unable to create application com.iifl.news.codereduce.app.IIFLApplication: java.lang.IllegalStateException: Module adapter for class com.iifl.news.codereduce.a.b could not be loaded. Please ensure that code generation was run for this module.
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4521)
        at android.app.ActivityThread.access$1500(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1339)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        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)
 Caused by: java.lang.IllegalStateException: Module adapter for class com.iifl.news.codereduce.a.b could not be loaded. Please ensure that code generation was run for this module.
        at dagger.internal.FailoverLoader$1.create(Unknown Source)
        at dagger.internal.FailoverLoader$1.create(Unknown Source)
        at dagger.internal.Memoizer.get(Unknown Source)
        at dagger.internal.FailoverLoader.getModuleAdapter(Unknown Source)
        at dagger.internal.Modules.loadModules(Unknown Source)
        at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(Unknown Source)
        at dagger.ObjectGraph$DaggerObjectGraph.access$000(Unknown Source)
        at dagger.ObjectGraph.create(Unknown Source)
        at com.iifl.news.codereduce.app.IIFLApplication.onCreate(Unknown    Source)
        at     android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
            at           

I had also tried using -keep class com.iifl.news.codereduce.{ *; } -dontwarn com.iifl.news.codereduce.** -keep class com.iifl.news.codereduce.{ *; } -dontwarn com.iifl.news.codereduce.** But still in release mode it crash and in debug mode runs well.

I had also tried adding androidTestApt 'com.squareup.dagger:dagger-compiler:1.2.2' in dependencies. But No luck

I had the same problem. The problem was proguard is removing unused class methods when the app launches, but the app may need those class methods later down on the way for example when you switching to other activity or exiting the app, and that was when the app crashed. You need to change minifyEnabled attribute to false to keep unused methods permanently. But still you can shrink all the files during release using a shrink attribute. Shrinking may boost app's performance.

    release {
        minifyEnabled false //keeps unused methods instead of removing them
        shrinkResources true //to shrink files
        proguardFiles getDefaultProguardFile('proguard-android.txt'),     'proguard-rules.pro'
    }

If you are using Retrofit I assume you will have classes that you will use as POJOs to convert to from JSON. (ie The Java objects you get created when Retrofit returns a response)

These classes should not be obfuscated by proguard and you will need to remove them as follows (putting them inside a single package will help!):

-keep class com.app.example.{ *; }
-dontwarn com.app.example.**

build.gradle文件中删除apt 'com.squareup.dagger:dagger-compiler:1.2.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM