diff --git a/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java b/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java index 4a591bf..f6aca1c 100644 --- a/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java +++ b/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java @@ -34,7 +34,7 @@ public File guess() { try { ClassLoader classLoader = guessSuitableClassLoader(); // Check that we have an instance of the PathClassLoader. - Class clazz = Class.forName("dalvik.system.PathClassLoader"); + Class clazz = Class.forName("dalvik.system.BaseDexClassLoader"); clazz.cast(classLoader); // Use the toString() method to calculate the data directory. String pathFromThisClassLoader = getPathFromThisClassLoader(classLoader, clazz); @@ -44,7 +44,16 @@ public File guess() { } } catch (ClassCastException ignored) { } catch (ClassNotFoundException ignored) { + } catch (Throwable ignored) { } + + // Fallback + File fallback = guessContextCacheDir(); + if (fallback != null) { + System.out.println("DexMaker: Guessed dexcache directory via ActivityThread: " + fallback.getAbsolutePath()); + return fallback; + } + return null; } @@ -217,6 +226,25 @@ Integer getProcessUid() { } } + private File guessContextCacheDir() { + try { + Class activityThreadClass = Class.forName("android.app.ActivityThread"); + Method currentApplicationMethod = activityThreadClass.getMethod("currentApplication"); + Object app = currentApplicationMethod.invoke(null); + if (app != null) { + Method getCacheDirMethod = app.getClass().getMethod("getCacheDir"); + File cacheDir = (File) getCacheDirMethod.invoke(app); + if (cacheDir != null) { + if (isWriteableDirectory(cacheDir)) { + return cacheDir; + } + } + } + } catch (Throwable ignored) { + } + return null; + } + File guessUserDataDirectory(String packageName) { Integer uid = getProcessUid(); if (uid == null) {