diff options
author | Brett Chabot <brettchabot@google.com> | 2018-10-18 12:11:59 -0700 |
---|---|---|
committer | Brett Chabot <brettchabot@google.com> | 2018-10-18 12:11:59 -0700 |
commit | 82e6716abb48f3faeb659f732e43071ca242a621 (patch) | |
tree | 68f7a0920d66e766f410e52f2dd984e7533228d9 /library/src/androidx/multidex/MultiDex.java | |
parent | eb24b3049f75b76e115d4d5a7ba474e3681a09c8 (diff) | |
download | multidex-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
Diffstat (limited to 'library/src/androidx/multidex/MultiDex.java')
-rw-r--r-- | library/src/androidx/multidex/MultiDex.java | 57 |
1 files changed, 37 insertions, 20 deletions
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 |