summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Roussel <yroussel@google.com>2015-05-12 17:40:52 +0200
committerYohann Roussel <yroussel@google.com>2015-05-26 09:39:02 +0200
commit606af94785cb96d418d87fe5a90bb2e09ccfa97f (patch)
tree5d7d7b487834e4b488dc1a9a607f9aa980594584
parent5c2dd97be0a197f6d4004f9528026025c7e4f248 (diff)
downloadmultidex-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.java43
-rw-r--r--library/src/android/support/multidex/MultiDexExtractor.java28
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 {