diff options
author | Yohann Roussel <yroussel@google.com> | 2015-05-12 17:40:52 +0200 |
---|---|---|
committer | Yohann Roussel <yroussel@google.com> | 2015-05-26 09:39:02 +0200 |
commit | 606af94785cb96d418d87fe5a90bb2e09ccfa97f (patch) | |
tree | 5d7d7b487834e4b488dc1a9a607f9aa980594584 | |
parent | 5c2dd97be0a197f6d4004f9528026025c7e4f248 (diff) | |
download | multidex-606af94785cb96d418d87fe5a90bb2e09ccfa97f.tar.gz |
Use Context.getFilesDir as a backup dex locationandroid-m-preview-2
On some devices it seems impossible to read or write the application
data directory. There, creating code_cache at the proper location is
impossible. In this case fallback to the 'files' directory. This may
lead to not cleaning the useless extracted secondary dex files if one
such devices is ever updated to L.
Bug: https://code.google.com/p/android/issues/detail?id=79388
Change-Id: I4b6725572f10fd511992dc8a5043d2f135abd3a5
-rw-r--r-- | library/src/android/support/multidex/MultiDex.java | 43 | ||||
-rw-r--r-- | library/src/android/support/multidex/MultiDexExtractor.java | 28 |
2 files changed, 41 insertions, 30 deletions
diff --git a/library/src/android/support/multidex/MultiDex.java b/library/src/android/support/multidex/MultiDex.java index 8d5e1ab..1e04c19 100644 --- a/library/src/android/support/multidex/MultiDex.java +++ b/library/src/android/support/multidex/MultiDex.java @@ -60,8 +60,9 @@ public final class MultiDex { private static final String OLD_SECONDARY_FOLDER_NAME = "secondary-dexes"; - private static final String SECONDARY_FOLDER_NAME = "code_cache" + File.separator + - "secondary-dexes"; + private static final String CODE_CACHE_NAME = "code_cache"; + + private static final String CODE_CACHE_SECONDARY_FOLDER_NAME = "secondary-dexes"; private static final int MAX_SUPPORTED_SDK_VERSION = 20; @@ -155,7 +156,7 @@ public final class MultiDex { + "continuing without cleaning.", t); } - File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME); + File dexDir = getDexDir(context, applicationInfo); List<File> files = MultiDexExtractor.load(context, applicationInfo, dexDir, false); if (checkValidZipFiles(files)) { installSecondaryDexes(loader, dexDir, files); @@ -363,6 +364,42 @@ public final class MultiDex { } } + private static File getDexDir(Context context, ApplicationInfo applicationInfo) + throws IOException { + File cache = new File(applicationInfo.dataDir, CODE_CACHE_NAME); + try { + mkdirChecked(cache); + } catch (IOException e) { + /* If we can't emulate code_cache, then store to filesDir. This means abandoning useless + * files on disk if the device ever updates to android 5+. But since this seems to + * happen only on some devices running android 2, this should cause no pollution. + */ + cache = new File(context.getFilesDir(), CODE_CACHE_NAME); + mkdirChecked(cache); + } + File dexDir = new File(cache, CODE_CACHE_SECONDARY_FOLDER_NAME); + mkdirChecked(dexDir); + return dexDir; + } + + private static void mkdirChecked(File dir) throws IOException { + dir.mkdir(); + if (!dir.isDirectory()) { + File parent = dir.getParentFile(); + if (parent == null) { + Log.e(TAG, "Failed to create dir " + dir.getPath() + ". Parent file is null."); + } else { + Log.e(TAG, "Failed to create dir " + dir.getPath() + + ". parent file is a dir " + parent.isDirectory() + + ", a file " + parent.isFile() + + ", exists " + parent.exists() + + ", readable " + parent.canRead() + + ", writable " + parent.canWrite()); + } + throw new IOException("Failed to create directory " + dir.getPath()); + } + } + /** * Installer for platform versions 19. */ diff --git a/library/src/android/support/multidex/MultiDexExtractor.java b/library/src/android/support/multidex/MultiDexExtractor.java index 27da6b3..4aef9f2 100644 --- a/library/src/android/support/multidex/MultiDexExtractor.java +++ b/library/src/android/support/multidex/MultiDexExtractor.java @@ -251,15 +251,7 @@ final class MultiDexExtractor { /** * This removes any files that do not have the correct prefix. */ - private static void prepareDexDir(File dexDir, final String extractedFilePrefix) - throws IOException { - /* mkdirs() has some bugs, especially before jb-mr1 and we have only a maximum of one parent - * to create, lets stick to mkdir(). - */ - File cache = dexDir.getParentFile(); - mkdirChecked(cache); - mkdirChecked(dexDir); - + private static void prepareDexDir(File dexDir, final String extractedFilePrefix) { // Clean possible old files FileFilter filter = new FileFilter() { @@ -284,24 +276,6 @@ final class MultiDexExtractor { } } - private static void mkdirChecked(File dir) throws IOException { - dir.mkdir(); - if (!dir.isDirectory()) { - File parent = dir.getParentFile(); - if (parent == null) { - Log.e(TAG, "Failed to create dir " + dir.getPath() + ". Parent file is null."); - } else { - Log.e(TAG, "Failed to create dir " + dir.getPath() + - ". parent file is a dir " + parent.isDirectory() + - ", a file " + parent.isFile() + - ", exists " + parent.exists() + - ", readable " + parent.canRead() + - ", writable " + parent.canWrite()); - } - throw new IOException("Failed to create cache directory " + dir.getPath()); - } - } - private static void extract(ZipFile apk, ZipEntry dexFile, File extractTo, String extractedFilePrefix) throws IOException, FileNotFoundException { |