summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrett Chabot <brettchabot@google.com>2018-10-18 12:11:59 -0700
committerBrett Chabot <brettchabot@google.com>2018-10-18 12:11:59 -0700
commit82e6716abb48f3faeb659f732e43071ca242a621 (patch)
tree68f7a0920d66e766f410e52f2dd984e7533228d9
parenteb24b3049f75b76e115d4d5a7ba474e3681a09c8 (diff)
downloadmultidex-82e6716abb48f3faeb659f732e43071ca242a621.tar.gz
Fix compatibility with Robolectric.
Robolectric at somepoint changed to return a valid Java ClassLoader from Context.getClassLoader(), breaking the check in MultiDex. Modify this check to ensure a valid Dex compatible classloader. Test: Added integration tests in Robolectric; m -j checkbuild Change-Id: I9df517e25460daa5fabfe8cba88cdc5d9bb16de2
-rw-r--r--library/Android.bp3
-rw-r--r--library/build.gradle2
-rw-r--r--library/src/androidx/multidex/MultiDex.java57
3 files changed, 40 insertions, 22 deletions
diff --git a/library/Android.bp b/library/Android.bp
index bc82325..6ba5804 100644
--- a/library/Android.bp
+++ b/library/Android.bp
@@ -31,7 +31,8 @@ genrule {
java_library_static {
name: "android-support-multidex",
- sdk_version: "4",
+ sdk_version: "15",
+ min_sdk_version: "4",
srcs: [
"src/**/*.java",
],
diff --git a/library/build.gradle b/library/build.gradle
index 83cbd27..1f17008 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -36,7 +36,7 @@ task makeVersionFile(type:Exec) {
}
android {
- compileSdkVersion 4
+ compileSdkVersion gradle.currentSdk
defaultConfig {
minSdkVersion 4
diff --git a/library/src/androidx/multidex/MultiDex.java b/library/src/androidx/multidex/MultiDex.java
index 69ff889..30cb886 100644
--- a/library/src/androidx/multidex/MultiDex.java
+++ b/library/src/androidx/multidex/MultiDex.java
@@ -22,7 +22,9 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.util.Log;
+
import dalvik.system.DexFile;
+
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
@@ -218,28 +220,11 @@ public final class MultiDex {
+ System.getProperty("java.vm.version") + "\"");
}
- /* The patched class loader is expected to be a descendant of
- * dalvik.system.BaseDexClassLoader. We modify its
- * dalvik.system.DexPathList pathList field to append additional DEX
- * file entries.
+ /* The patched class loader is expected to be a ClassLoader capable of loading DEX
+ * bytecode. We modify its pathList field to append additional DEX file entries.
*/
- ClassLoader loader;
- try {
- loader = mainContext.getClassLoader();
- } catch (RuntimeException e) {
- /* Ignore those exceptions so that we don't break tests relying on Context like
- * a android.test.mock.MockContext or a android.content.ContextWrapper with a
- * null base Context.
- */
- Log.w(TAG, "Failure while trying to obtain Context class loader. " +
- "Must be running in test mode. Skip patching.", e);
- return;
- }
+ ClassLoader loader = getDexClassloader(mainContext);
if (loader == null) {
- // Note, the context class loader is null when running Robolectric tests.
- Log.e(TAG,
- "Context class loader is null. Must be running in test mode. "
- + "Skip patching.");
return;
}
@@ -286,6 +271,38 @@ public final class MultiDex {
}
}
+ /**
+ * Returns a {@link Classloader} from the {@link Context} that is capable of reading dex
+ * bytecode or null if the Classloader is not dex-capable e.g: when running on a JVM testing
+ * environment such as Robolectric.
+ */
+ private static ClassLoader getDexClassloader(Context context) {
+ ClassLoader loader;
+ try {
+ loader = context.getClassLoader();
+ } catch (RuntimeException e) {
+ /* Ignore those exceptions so that we don't break tests relying on Context like
+ * a android.test.mock.MockContext or a android.content.ContextWrapper with a
+ * null base Context.
+ */
+ Log.w(TAG, "Failure while trying to obtain Context class loader. "
+ + "Must be running in test mode. Skip patching.", e);
+ return null;
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ if (loader instanceof dalvik.system.BaseDexClassLoader) {
+ return loader;
+ }
+ } else if (loader instanceof dalvik.system.DexClassLoader
+ || loader instanceof dalvik.system.PathClassLoader) {
+ return loader;
+ }
+ Log.e(TAG, "Context class loader is null or not dex-capable. "
+ + "Must be running in test mode. Skip patching.");
+ return null;
+ }
+
private static ApplicationInfo getApplicationInfo(Context context) {
try {
/* Due to package install races it is possible for a process to be started from an old