Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.** 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

like image 632
PPD Avatar asked May 22 '15 09:05

PPD


People also ask

Why does an app keep crashing as soon as I open it?

Apps on Android can crash because of low storage space, too many apps running simultaneously, a weak internet connection, or not having the proper app updates installed.

How do you fix an app that keeps crashing?

To fix Android apps that keep crashing: To do this, go to Settings and open Apps. Under Your apps, you'll see a list of the apps currently installed on your device. From the list, tap the app that keeps crashing and tap Force stop in the bottom right corner. Then try opening the app again.

How do I force an app to not crash?

The easiest way to fix an app that keeps crashing on your Android smartphone is to simply force stop it and open it again. To do this, go to Settings -> Apps and select the app that keeps crashing. Tap on the app's name and then tap on 'Force stop'. Now try opening the app again and see if it works well.

How do you troubleshoot the Android application which is crashing frequently?

The shortage of storage capacity on your device is another cause of Android Apps crashing. When an app fails, restarting it usually solves the problem. However, if you have an app that crashes or closes unexpectedly, restarting it will not address the problem because it will most likely crash again.


2 Answers

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'
    }
like image 164
Josi Avatar answered Oct 30 '22 10:10

Josi


If you are using Retrofit I assume you will have classes that you will use as POJOs to convert to from JSON. (i.e. 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.**
like image 21
Ed George Avatar answered Oct 30 '22 10:10

Ed George