Search in sources :

Example 21 with DexFile

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);
    }
}
Also used : Field(java.lang.reflect.Field) DexFile(dalvik.system.DexFile) IOException(java.io.IOException) NClassLoader(android.taobao.atlas.startup.NClassLoader)

Example 22 with DexFile

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;
}
Also used : Field(java.lang.reflect.Field) ZipFile(java.util.zip.ZipFile) DexFile(dalvik.system.DexFile) File(java.io.File)

Example 23 with DexFile

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;
}
Also used : Constructor(java.lang.reflect.Constructor) ZipFile(java.util.zip.ZipFile) DexFile(dalvik.system.DexFile) File(java.io.File) IOException(java.io.IOException)

Example 24 with DexFile

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));
}
Also used : FilenameFilter(java.io.FilenameFilter) CountDownLatch(java.util.concurrent.CountDownLatch) DexFile(dalvik.system.DexFile) File(java.io.File)

Example 25 with DexFile

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;
}
Also used : DexFile(dalvik.system.DexFile) File(java.io.File) DexFile(dalvik.system.DexFile) IOException(java.io.IOException)

Aggregations

DexFile (dalvik.system.DexFile)59 File (java.io.File)32 IOException (java.io.IOException)28 ArrayList (java.util.ArrayList)17 Field (java.lang.reflect.Field)13 ZipFile (java.util.zip.ZipFile)13 Method (java.lang.reflect.Method)11 DexClassLoader (dalvik.system.DexClassLoader)9 Enumeration (java.util.Enumeration)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ApplicationInfo (android.content.pm.ApplicationInfo)3 NClassLoader (android.taobao.atlas.startup.NClassLoader)2 URL (java.net.URL)2 HashSet (java.util.HashSet)2 Application (android.app.Application)1 ActivityNotFoundException (android.content.ActivityNotFoundException)1 Context (android.content.Context)1 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)1 Main (com.android.dx.command.dexer.Main)1 Action (com.jia.base.annotation.Action)1