use of dalvik.system.DexFile in project atlas by alibaba.
the class KernalBundle method patchKernalDex.
public void patchKernalDex(Application application) throws Exception {
DexFile[] dexFile = archive.getOdexFile();
if ((dexFile != null && dexFile.length > 0) || archive.getLibraryDirectory().exists()) {
boolean needReplaceClassLoader = needReplaceClassLoader(application);
boolean dexPatch = dexFile[dexFile.length - 1].getName().contains(KernalBundleArchive.DEXPATCH_DIR);
int newFrameworkPropertiesDexIndex;
if (dexPatch) {
newFrameworkPropertiesDexIndex = 0;
} else {
newFrameworkPropertiesDexIndex = dexFile.length - 1;
}
// 临时处理方案,需要替换为dexopt时传入classsLoader以兼容8.0
patchWithApk = dexPatch && (TextUtils.isEmpty(KernalVersionManager.instance().currentVersionName()) || KernalVersionManager.instance().currentVersionName().equals(KernalConstants.INSTALLED_VERSIONNAME));
if (!needReplaceClassLoader) {
Log.e("KernalBundle", "no need replace Classloader!");
FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass("android.taobao.atlas.framework.FrameworkProperties", application.getClassLoader());
} else if (patchWithApk) {
Log.e("KernalBundle", "need replace Classloader && patchWithApk!");
replaceClassLoader = new NClassLoader(".", KernalBundle.class.getClassLoader().getParent());
if (needReplaceClassLoader) {
try {
NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), replaceClassLoader);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass("android.taobao.atlas.framework.FrameworkProperties", replaceClassLoader);
} else {
Log.e("KernalBundle", "need replace Classloader && load FrameworkPropertiesClazz to NclassLoader!");
replaceClassLoader = new NClassLoader(".", KernalBundle.class.getClassLoader().getParent());
if (needReplaceClassLoader) {
try {
NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), replaceClassLoader);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass("android.taobao.atlas.framework.FrameworkProperties", replaceClassLoader);
}
// for mini sdk 21
if (FrameworkPropertiesClazz == null) {
Log.e("KernalBundle", "FrameworkPropertiesClazz is null, load from source apk");
FrameworkPropertiesClazz = Class.forName("android.taobao.atlas.framework.FrameworkProperties");
}
if (FrameworkPropertiesClazz == null && isDeubgMode()) {
Log.e("KernalBundle", "main dex is not match, library awo test?");
return;
}
Field versionField = FrameworkPropertiesClazz.getDeclaredField("version");
versionField.setAccessible(true);
String version = (String) versionField.get(FrameworkPropertiesClazz.newInstance());
if (!KernalVersionManager.instance().currentVersionName().equals(version)) {
if (isDeubgMode()) {
Log.e("KernalBundle", "main dex is not match, awo test?");
} else {
throw new RuntimeException(String.format("maindex version is not mismatch %s vs %s!", KernalVersionManager.instance().currentVersionName(), version));
}
}
installKernalBundle(KernalConstants.baseContext.getClassLoader(), archive.getArchiveFile(), archive.getOdexFile(), archive.getLibraryDirectory());
prepareRuntimeVariables(application);
prepareKernalConstant(application);
}
}
use of dalvik.system.DexFile in project atlas by alibaba.
the class KernalBundle method removeOrignalElement.
private boolean removeOrignalElement(Object instance, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field jlrField = findField(instance, fieldName);
Object[] original = (Object[]) jlrField.get(instance);
for (int x = 0; x < original.length; x++) {
Object element = original[x];
Field dexFileField = element.getClass().getDeclaredField("dexFile");
dexFileField.setAccessible(true);
File apkFile = findDexRawFile(element);
if (apkFile != null) {
if (apkFile.getAbsolutePath() != null && apkFile.getAbsolutePath().contains(KernalConstants.baseContext.getPackageName())) {
dexFileField.set(element, null);
break;
}
}
}
return true;
}
use of dalvik.system.DexFile in project atlas by alibaba.
the class KernalBundle method makeDexElement.
public static Object[] makeDexElement(File file, DexFile[] dex) throws Exception {
Object[] objects = new Object[dex.length];
for (int i = 0; i < dex.length; i++) {
try {
Class Element = Class.forName("dalvik.system.DexPathList$Element");
if (Build.VERSION.SDK_INT > 25 || Build.VERSION.SDK_INT == 25 && Build.VERSION.PREVIEW_SDK_INT > 0) {
Constructor cons = getElementConstructor(Element, constructorArgsO);
objects[i] = cons.newInstance(dex[i], file);
} else {
File apkFile = new File(KernalConstants.baseContext.getApplicationInfo().sourceDir);
Constructor cons = getElementConstructor(Element, constructorArgs1);
if (cons != null) {
objects[i] = cons.newInstance(apkFile, false, apkFile, dex[i]);
} else {
cons = getElementConstructor(Element, constructorArgs2);
if (cons != null) {
objects[i] = cons.newInstance(apkFile, apkFile, dex[i]);
} else {
cons = getElementConstructor(Element, constructorArgs3);
if (cons != null) {
objects[i] = cons.newInstance(apkFile, null, dex[i]);
}
}
}
}
} catch (Exception e) {
throw new RuntimeException("make DexElement fail", e);
}
}
return objects;
}
use of dalvik.system.DexFile in project atlas by alibaba.
the class BundleReleaser method dexOptimization.
private void dexOptimization() {
Log.e(TAG, "dexOptimization start");
File[] validDexes = reversionDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String pathname) {
if (!DexReleaser.isArt() || externalStorage) {
return pathname.endsWith(DEX_SUFFIX);
} else {
return pathname.endsWith(".zip");
}
}
});
File[] rawMainDexZip = reversionDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String pathname) {
return pathname.endsWith(".zip");
}
});
if (validDexes != null && validDexes.length > 0) {
validDexes = sortDexs(validDexes);
if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT <= 24) {
PatchDexProfile.instance(RuntimeVariables.androidApplication).disableJitCompile();
}
} else if (rawMainDexZip != null) {
validDexes = rawMainDexZip;
}
dexFiles = new DexFile[validDexes.length];
if (!hasReleased) {
Log.e(TAG, "start dexopt | hasRelease : " + hasReleased);
final CountDownLatch countDownLatch = new CountDownLatch(validDexes.length);
for (int i = 0; i < validDexes.length; i++) {
final int j = i;
final File[] finalValidDexes = validDexes;
service.submit(new Runnable() {
@Override
public void run() {
dexFiles[j] = dexoptInternal(finalValidDexes[j]);
countDownLatch.countDown();
}
});
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
Log.e(TAG, "start dexopt | hasRelease : " + hasReleased);
for (int i = 0; i < validDexes.length; i++) {
dexFiles[i] = dexoptInternal(validDexes[i]);
}
}
Log.e(TAG, "dex opt done");
handler.sendMessage(handler.obtainMessage(MSG_ID_DEX_OPT_DONE));
}
use of dalvik.system.DexFile in project atlas by alibaba.
the class BundleReleaser method dexoptInternal.
private DexFile dexoptInternal(File validDex) {
long startTime = System.currentTimeMillis();
DexFile dexFile = null;
String optimizedPath = optimizedPathFor(validDex, dexOptDir());
try {
if (!externalStorage) {
if (!new File(optimizedPath).exists()) {
Log.e(TAG, "odex not exist");
}
} else {
// interpretOnly
if (Build.VERSION.SDK_INT >= 21 && isVMMultidexCapable(System.getProperty("java.vm.version"))) {
optimizedPath = KernalConstants.baseContext.getFilesDir() + File.separator + "fake.dex";
new File(optimizedPath).createNewFile();
dexFile = DexFileCompat.loadDex(KernalConstants.baseContext, validDex.getPath(), optimizedPath, 0);
} else {
dexFile = DexFileCompat.loadDex(KernalConstants.baseContext, validDex.getPath(), optimizedPath, 0);
}
}
boolean result = verifyDexFile(dexFile, optimizedPath);
if (!result) {
handler.sendMessage(handler.obtainMessage(MSG_ID_RELEASE_FAILED));
} else {
Log.e(TAG, "oat length:" + String.valueOf(new File(optimizedPath).length()));
}
} catch (Exception e) {
e.printStackTrace();
handler.sendMessage(handler.obtainMessage(MSG_ID_RELEASE_FAILED));
} finally {
Log.e(TAG, String.format("dex %s consume %d ms", validDex.getAbsolutePath(), System.currentTimeMillis() - startTime));
}
return dexFile;
}
Aggregations