androidandroid-asynctaskgoogle-play

App Crashes in release but works fine in Debug mode


I have app uploaded on Play Store. It works fine in Debug mode but when I download same APK (Release mode) from play store, it gets crashed. I am unable to figure out and Stack Trace is not giving exact error location.

java.lang.RuntimeException: at android.os.AsyncTask$3.done (AsyncTask.java:318) at java.util.concurrent.FutureTask.finishCompletion (FutureTask.java:354) at java.util.concurrent.FutureTask.setException (FutureTask.java:223) at java.util.concurrent.FutureTask.run (FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:243) at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607) at java.lang.Thread.run (Thread.java:761) Caused by: java.lang.NullPointerException: at com.biocare.fots.HomeActivity$GetEmpDetailsTask.doInBackground (HomeActivity.java) or .onPostExecute (HomeActivity.java) at com.biocare.fots.HomeActivity$GetEmpDetailsTask.doInBackground (HomeActivity.java) at android.os.AsyncTask$2.call (AsyncTask.java:304) at java.util.concurrent.FutureTask.run (FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:243) at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607) at java.lang.Thread.run (Thread.java:761)

Above stack trace is copied from Play Store Developer Console. Same error is shown in Firebase console.

enter image description here

Here is my AsyncTask Code:

 private static class GetEmpDetailsTask extends AsyncTask<Void, Void, Void> {

    WeakReference<HomeActivity> mContext;

    GetEmpDetailsTask(HomeActivity context) {
        mContext = new WeakReference<>(context);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... voids) {
        if(android.os.Debug.isDebuggerConnected())
            android.os.Debug.waitForDebugger();
        AppDatabase appDatabase = AppDatabase.getAppDatabaseInstance(
                mContext.get());
        Employee employee = appDatabase.employeeDAO().get();
        FotApplication.Employee.Id = employee.employeeId;
        FotApplication.Employee.Name = employee.firstName + " "
                + employee.lastName;
        FotApplication.Employee.Designation = employee.empDesignationName;
        FotApplication.Employee.DesignationDesc = employee.empDesignationName;
        FotApplication.Employee.Email = employee.email;
        return null;
    }


    @Override
    protected void onPostExecute(Void aVoid) {
        mContext.get().mTvEmpName.setText(FotApplication.Employee.Name);
        mContext.get().mTvEmpEmail.setText(FotApplication.Employee.Email);
    }
}

And here is my build.gradle (Module: app):

apply plugin: 'com.android.application'


android {
    signingConfigs {
        config {
            keyAlias 'abc'
            keyPassword 'test'
            storeFile file('path/to/keystore.jks')
            storePassword 'testpass'
        }
    }
    compileSdkVersion 29
    defaultConfig {
        applicationId "com.myapp.fats"
        minSdkVersion 22
        targetSdkVersion 29
        versionCode 38
        versionName "2.1.9"
        vectorDrawables.useSupportLibrary = true
    }
    buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    productFlavors {
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.google.android.gms:play-services-location:17.0.0'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'com.google.android.gms:play-services-places:17.0.0'
    implementation 'com.jakewharton:butterknife:8.6.0'
    implementation 'com.google.firebase:firebase-messaging:19.0.1'
    implementation 'com.google.firebase:firebase-core:17.0.1'
    implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
    implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
    annotationProcessor 'com.jakewharton:butterknife:8.6.0'
    annotationProcessor 'androidx.room:room-compiler:2.1.0'
    implementation 'androidx.room:room-runtime:2.1.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'
    implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
    implementation 'de.hdodenhof:circleimageview:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.0.0'
    implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
    implementation 'com.wang.avi:library:2.1.3'
    implementation 'androidx.gridlayout:gridlayout:1.0.0'
    implementation ('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') {
        transitive = true
    }
}
repositories {
    mavenCentral()
}

apply plugin: 'com.google.gms.google-services'
apply plugin: 'io.fabric'

EDIT 1:

Logcat from Android Studio:

 Process: com.biocare.fots, PID: 15978
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:353)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.biocare.database.n.b' on a null object reference
    at com.biocare.fots.HomeActivity$a.a(Unknown Source:20)
    at com.biocare.fots.HomeActivity$a.doInBackground(Unknown Source:2)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)

Solution

  • I guess, that if your DAO (f.e. Room) uses reflection, when you build release apk with minifyEnable=true, your DAO can't find something. Try to check your proguard.

    UPD Yes, you have problem with obfuscation. 'java.lang.String com.biocare.database.n.b' this 'n.b' means that you had right path before obfuscation, but after obfuscation path was changed to values 'n' and 'b'. You should add this files (I don't know certain files, because I don't know your code) in proguard exclude list.

    You can read more in proguard documentation. This can be useful too