Search in sources :

Example 1 with PatchException

use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.

the class ApkPatch method buildPrepareClass.

private static Set<String> buildPrepareClass(File smaliDir, List<File> newFiles, DexDiffInfo info) throws PatchException {
    Set<DexBackedClassDef> classes = Sets.newHashSet();
    classes = SmaliDiffUtils.scanClasses(smaliDir, newFiles);
    ArrayList<String> methods = new ArrayList<String>();
    {
        Set<DexBackedMethod> tempSet = info.getModifiedMethods();
        for (DexBackedMethod methodRef : tempSet) {
            String template = methodRef.getDefiningClass() + "->" + methodRef.getName();
            methods.add(template);
            System.out.println("template: " + template);
            if (superClasses.containsKey(methodRef.getDefiningClass())) {
                ArrayList<String> derivedClasses = superClasses.get(methodRef.getDefiningClass());
                for (int i = 0; i < derivedClasses.size(); i++) {
                    template = derivedClasses.get(i) + "->" + methodRef.getName();
                    System.out.println("template: " + template);
                    methods.add(template);
                }
            }
        }
    }
    Set<String> prepareClasses = new HashSet<String>();
    try {
        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        for (DexBackedClassDef classDef : classes) {
            currentClassType = null;
            String className = TypeGenUtil.newType(classDef.getType());
            // baksmali.disassembleClass(classDef, outFileNameHandler, options);
            File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
            if (!smaliFile.exists()) {
                continue;
            }
            //增加class注解到prepare
            getClassAnnotaionPrepareClasses(classDef, prepareClasses, info);
            BufferedReader br = new BufferedReader(new FileReader(smaliFile));
            // 一次读入一行,直到读入null为文件结束
            String data = br.readLine();
            while (data != null) {
                boolean find = false;
                for (String m : methods) {
                    if (data.contains(m)) {
                        find = true;
                        break;
                    }
                }
                if (find) {
                    prepareClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));
                    System.out.println("prepare class: " + className);
                    break;
                }
                // 接着读下一行
                data = br.readLine();
            }
            br.close();
        }
    } catch (Exception e) {
        throw new PatchException(e);
    }
    for (DexBackedMethod method : info.getModifiedMethods()) {
        prepareClasses.add(method.getDefiningClass().substring(1, method.getDefiningClass().length() - 1).replace("/", "."));
    }
    //        getMethodAnnotaionPrepareClasses(info,prepareClasses);
    return prepareClasses;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) DexBackedMethod(org.jf.dexlib2.dexbacked.DexBackedMethod) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) ArrayList(java.util.ArrayList) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) PatchException(com.taobao.android.differ.dex.PatchException) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) File(java.io.File) HashSet(java.util.HashSet)

Example 2 with PatchException

use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.

the class ApkPatch method doPatch.

public File doPatch() throws PatchException {
    try {
        File aptchFolder = new File(out, name);
        File smaliDir = new File(aptchFolder, "smali");
        if (!smaliDir.exists()) {
            smaliDir.mkdirs();
        }
        try {
            FileUtils.cleanDirectory(smaliDir);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        File dexFile = new File(aptchFolder, "diff.dex");
        if (dexFile.exists() && !dexFile.delete()) {
            throw new RuntimeException("diff.dex can't be removed.");
        }
        File outFile = new File(aptchFolder, "diff" + SUFFIX);
        if (outFile.exists() && !outFile.delete()) {
            throw new RuntimeException("diff" + SUFFIX + " can't be removed.");
        }
        currentTimeStamp = System.currentTimeMillis();
        DexDiffer dexDiffer = new DexDiffer(baseFiles, newFiles, 19);
        // 创建白名单过滤类
        if ((this.filterPath != null) && !(this.filterPath.equals(""))) {
            dexDiffer.createFilter(this.filterPath);
        }
        //diff
        DexDiffInfo info = dexDiffer.doDiff();
        dexDiffer.setDexDiffFilter(new AndFixFilterImpl(info));
        //diffFilter
        dexDiffer.dexFilter();
        info.update();
        //写json
        if (null != diffFile && null != diffJsonFile) {
            info.writeToFile(name, diffFile, diffJsonFile);
        }
        //生成dex
        classes = SmaliDiffUtils.buildCode(smaliDir, dexFile, info);
        if (null == classes || classes.size() <= 0) {
            return null;
        }
        //是否修改dex
        if (APatchTool.debug) {
            PatchMethodTool.modifyMethod(dexFile.getAbsolutePath(), dexFile.getAbsolutePath(), true);
        }
        File smaliDir2 = new File(aptchFolder, "smali2");
        if (!smaliDir2.exists()) {
            smaliDir2.mkdirs();
        }
        try {
            FileUtils.cleanDirectory(smaliDir2);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        prepareClasses = buildPrepareClass(smaliDir2, newFiles, info);
        DexDiffInfo.release();
        build(outFile, dexFile);
        File file = release(aptchFolder, dexFile, outFile);
        release();
        return file;
    } catch (Exception e) {
        throw new PatchException(e);
    }
}
Also used : DexDiffInfo(com.taobao.android.object.DexDiffInfo) DexDiffer(com.taobao.android.differ.dex.DexDiffer) IOException(java.io.IOException) PatchException(com.taobao.android.differ.dex.PatchException) File(java.io.File) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException)

Example 3 with PatchException

use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.

the class APatchTool method processBundleFiles.

/**
     * 生成bundle的apatch文件
     *
     * @param newBundleFile
     * @param baseBundleFile
     * @param patchTmpDir
     * @return
     */
private List<File> processBundleFiles(File newBundleFile, File baseBundleFile, File patchTmpDir, File diffFile, File diffJsonFile) throws PatchException, IOException, RecognitionException {
    String bundleName = FilenameUtils.getBaseName(newBundleFile.getName());
    if (!isModifyBundle(newBundleFile.getName()) || !onlyIncludeModifyBundle) {
        return null;
    }
    if (null != logger) {
        logger.info("[DiffApatch]" + bundleName);
    }
    final File newBundleUnzipFolder = new File(newBundleFile.getParentFile(), bundleName);
    final File baseBundleUnzipFolder = new File(baseBundleFile.getParentFile(), bundleName);
    if (null != baseBundleFile && baseBundleFile.isFile() && baseBundleFile.exists()) {
        // 解压文件
        ZipUtils.unzip(newBundleFile, newBundleUnzipFolder.getAbsolutePath());
        ZipUtils.unzip(baseBundleFile, baseBundleUnzipFolder.getAbsolutePath());
        // String patchBundleName = getBundleName(newBundleFile.getName());
        String patchBundleName = FilenameUtils.getBaseName(newBundleFile.getName().replace("lib", ""));
        if (null != patchBundleName) {
            patchBundleName = patchBundleName.replace(".", "_");
            List<File> bundlePatchs = createBundleAPatch(newBundleUnzipFolder, baseBundleUnzipFolder, patchTmpDir, patchBundleName, diffFile, diffJsonFile);
            return bundlePatchs;
        } else {
            throw new PatchException("Cannot found bundle:" + newBundleFile.getName() + " in modifyBundleInfos.");
        }
    }
    return null;
}
Also used : PatchException(com.taobao.android.differ.dex.PatchException) File(java.io.File)

Example 4 with PatchException

use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.

the class MergePatch method doMerge.

public File doMerge() throws PatchException {
    try {
        File dexFile = new File(out, "merge.dex");
        if (dexFile.exists() && !dexFile.delete()) {
            throw new RuntimeException("merge.dex can't be removed.");
        }
        File outFile = new File(out, "merge" + SUFFIX);
        if (dexFile.exists() && !dexFile.delete()) {
            throw new RuntimeException("merge" + SUFFIX + " can't be removed.");
        }
        if (patchs.length > 1) {
            mergeCode(dexFile);
            build(outFile, dexFile);
            return release(out, dexFile, outFile);
        } else if (patchs.length == 1) {
            return patchs[0];
        }
    } catch (Exception e) {
        throw new PatchException(e);
    }
    return null;
}
Also used : PatchException(com.taobao.android.differ.dex.PatchException) JarFile(java.util.jar.JarFile) File(java.io.File) IOException(java.io.IOException) PatchException(com.taobao.android.differ.dex.PatchException)

Example 5 with PatchException

use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.

the class SmaliDiffUtils method scanClasses.

public static Set<DexBackedClassDef> scanClasses(File smaliDir, List<File> newFiles) throws PatchException {
    Set<DexBackedClassDef> classes = Sets.newHashSet();
    try {
        for (File newFile : newFiles) {
            DexBackedDexFile newDexFile = DexFileFactory.loadDexFile(newFile, 19, true);
            Set<? extends DexBackedClassDef> dexClasses = newDexFile.getClasses();
            classes.addAll(dexClasses);
        }
        final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        for (DexBackedClassDef classDef : classes) {
            String className = classDef.getType();
            ApkPatch.currentClassType = null;
            AfBakSmali.disassembleClass(classDef, outFileNameHandler, getBuildOption(classes, 19), true, true);
            File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
        }
    } catch (Exception e) {
        throw new PatchException(e);
    }
    return classes;
}
Also used : DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) PatchException(com.taobao.android.differ.dex.PatchException) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File) RecognitionException(org.antlr.runtime.RecognitionException) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException)

Aggregations

PatchException (com.taobao.android.differ.dex.PatchException)10 File (java.io.File)5 IOException (java.io.IOException)4 PatchInfo (com.taobao.android.object.PatchInfo)2 ZipEntry (java.util.zip.ZipEntry)2 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)2 ClassFileNameHandler (org.jf.util.ClassFileNameHandler)2 DexDiffer (com.taobao.android.differ.dex.DexDiffer)1 BuildPatchInfos (com.taobao.android.object.BuildPatchInfos)1 DexDiffInfo (com.taobao.android.object.DexDiffInfo)1 PatchBundleInfo (com.taobao.android.object.PatchBundleInfo)1 ExecutorServicesHelper (com.taobao.android.task.ExecutorServicesHelper)1 BufferedReader (java.io.BufferedReader)1 FileReader (java.io.FileReader)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 ExecutionException (java.util.concurrent.ExecutionException)1 JarFile (java.util.jar.JarFile)1 JarOutputStream (java.util.jar.JarOutputStream)1