Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DexFile in 2.0 versions of Android Studio and Gradle

I am using the following code to instantiate all the classes included in a certain package.

DexFile df = new DexFile(getPackageCodePath());
for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
    String className = iter.nextElement();
    if (className.contains(packageName) && !className.contains("$")) {
        myClasses.add(Class.forName(className).newInstance());
    }
}

Unfortunately it is not working properly anymore. Since Android Studio 2 and Gradle 2.0.0, the DexFile entries no longer include all the classes within the app but only the classes belonging to the com.android.tools package.

Is this a known issue?

like image 491
anavarroma Avatar asked Jan 07 '23 06:01

anavarroma


1 Answers

Looks like this issue is related to the new InstantRun feature in the Android Plugin for Gradle 2.0.0.

getPackageCodePath() gets a String pointing towards the base.apk file in the Android file system. If we unzip that apk we can find one or several .dex files inside its root folder. The entries obtained from the method df.entries() iterates over the .dex files found in that root folder in order to obtain all of its compiled classes.

However, if we are using the new Android Plugin for Gradle, we will only find the .dex related to the android runtime and instant run (packages com.tools.android.fd.runtime, com.tools.android.fd.common and com.tools.android.tools.ir.api). Every other class will be compiled in several .dex files, zipped into a file called instant-run.zip and placed into the root folder of the apk.

That's why the code posted in the question is not able to list all the classes within the app. Still, this will only affect Debug builds since the Release ones don't feature InstantRun.

like image 161
anavarroma Avatar answered Jan 11 '23 02:01

anavarroma