Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassNotFoundException in signed apk

I got this error if I install and run a signed APK at my android device. This error does not come up if I just compile an app and run directly at device.

The Fragment, that seems to be missing is in my code in the project, not in any external library.

How could I investigate that error? i tried to rebuld, clean project etc.. Could I somehow find in APK if missing classes are created there?

hier is the error message:

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity

ComponentInfo{qua.com.bix/qua.com.bix.main.MainActivity}:
android.support.v4.app.q: Unable to instantiate fragment
qua.com.bix.main.MainLoadingFragment:
make sure class name exists, is public, and has an empty constructor that is public at Android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
    ....
    ....
    Caused by: android.support.v4.app.q: Unable to instantiate fragment qua.com.bix.main.MainLoadingFragment: make sure class name exists, is public, and has an empty constructor that is public
    ....
    ....
    Caused by: java.lang.ClassNotFoundException: Didn't find class "qua.com.bix.main.MainLoadingFragment" on path: /data/app/qua.com.bix-1.apk
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:64)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    at android.support.v4.app.o.a(Unknown Source) 
    at android.support.v4.app.o.a(Unknown Source) 

here is my build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "qua.com.bix"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
    }
    dexOptions{
        incremental true
        javaMaxHeapSize "4g"
    }
    useLibrary 'org.apache.http.legacy'
}

dependencies {
    compile 'com.android.support:multidex:1.0.1'
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.quadriq.qlib:qlib@aar'
    compile 'com.google.code.gson:gson:2.4'
    compile 'com.google.guava:guava:18.0'
    compile 'com.google.code.findbugs:jsr305:2.0.2'
    compile 'com.google.android.gms:play-services:8.3.0'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
    compile 'com.koushikdutta.ion:ion:2.+'
    compile 'joda-time:joda-time:2.9.1'
    compile 'com.github.michaelye.easydialog:easydialog:1.1'
}

Update: What helped for now, is disabling proguard, also adding -dontobfuscate to proguard-rules.pro. But is it a good practice to do this in that way?

the proguard-rules.pro is now:

-dontobfuscate
-dontwarn org.apache.lang.**
-dontwarn com.google.common.**
-dontwarn org.joda.**

Update 2: petey answered my question.

like image 419
user1908375 Avatar asked Mar 13 '23 21:03

user1908375


1 Answers

Proguard is obfuscating your vital app classes.

add the following lines to your proguard config file so that proguard will not mess with your application's classes that extend Activity, Application, BroadcastReceiver, ContentProvider, Preference, & Fragment (support and normal).

# Base Android exclusions, required for proper function of various components
-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.preference.Preference
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment

(if you arent using some of these feel free to remove those lines)

and then remove this line

-dontobfuscate

What helped for now, is disabling proguard, also adding -dontobfuscate to proguard-rules.pro. But is it a good practice to do this in that way?

It is only best practice if you do not care if someone decompiles your application. So, no. Mostly because you want to make a task like that as hard as possible on your production/release builds. Especially if you have In App Purchasing(IAP) or handle sensitive data.

like image 114
petey Avatar answered Mar 29 '23 16:03

petey