Search in sources :

Example 6 with TpatchInput

use of com.taobao.android.inputs.TpatchInput in project atlas by alibaba.

the class DexPatchTool method doPatch.

@Override
public PatchFile doPatch() throws Exception {
    TpatchInput tpatchInput = (TpatchInput) input;
    DexPatchFile tpatchFile = new DexPatchFile();
    tpatchFile.diffJson = new File(tpatchInput.outPatchDir, "diff.json");
    tpatchFile.patchInfo = new File(tpatchInput.outPatchDir, "patchInfo.json");
    final File patchTmpDir = new File(tpatchInput.outPatchDir, "dexpatch-tmp");
    final File mainDiffFolder = new File(patchTmpDir, tpatchInput.mainBundleName);
    patchTmpDir.mkdirs();
    FileUtils.cleanDirectory(patchTmpDir);
    mainDiffFolder.mkdirs();
    Profiler.release();
    Profiler.enter("unzip apks");
    // unzip apk
    File unzipFolder = unzipApk(((TpatchInput) input).outPatchDir);
    final File newApkUnzipFolder = new File(unzipFolder, NEW_APK_UNZIP_NAME);
    final File baseApkUnzipFolder = new File(unzipFolder, BASE_APK_UNZIP_NAME);
    Profiler.release();
    ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper();
    String taskName = "diffBundleTask";
    // 
    Collection<File> soFiles = FileUtils.listFiles(newApkUnzipFolder, new String[] { "so" }, true);
    // process remote bumdle
    if (tpatchInput.splitDiffBundle != null) {
        for (final Pair<BundleBO, BundleBO> bundle : ((TpatchInput) input).splitDiffBundle) {
            executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {

                @Override
                public Boolean call() throws Exception {
                    processBundleFiles(bundle.getSecond().getBundleFile(), bundle.getFirst().getBundleFile(), patchTmpDir);
                    return true;
                }
            });
        }
    }
    Profiler.enter("awbspatch");
    executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            // 得到主bundle的dex diff文件
            createBundleDexPatch(newApkUnzipFolder, baseApkUnzipFolder, mainDiffFolder, true);
            return true;
        }
    });
    for (final File soFile : soFiles) {
        System.out.println("do dexpatch:" + soFile.getAbsolutePath());
        final String relativePath = PathUtils.toRelative(newApkUnzipFolder, soFile.getAbsolutePath());
        if (null != tpatchInput.notIncludeFiles && pathMatcher.match(tpatchInput.notIncludeFiles, relativePath)) {
            continue;
        }
        executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                File destFile = new File(patchTmpDir, tpatchInput.mainBundleName + "/" + relativePath);
                File baseSoFile = new File(baseApkUnzipFolder, relativePath);
                if (isBundleFile(soFile)) {
                    processBundleFiles(soFile, baseSoFile, patchTmpDir);
                }
                return true;
            }
        });
    }
    executorServicesHelper.waitTaskCompleted(taskName);
    executorServicesHelper.stop();
    Profiler.release();
    Profiler.enter("ziptpatchfile");
    // zip file
    File patchFile = createDexPatchFile(tpatchInput.outPatchDir, patchTmpDir);
    tpatchFile.patchFile = patchFile;
    if (!patchFile.exists()) {
        return null;
    }
    PatchInfo curPatchInfo = createBasePatchInfo(patchFile);
    Profiler.release();
    Profiler.enter("writejson");
    BuildPatchInfos buildPatchInfos = new BuildPatchInfos();
    buildPatchInfos.getPatches().add(curPatchInfo);
    buildPatchInfos.setBaseVersion(input.baseApkBo.getVersionName());
    buildPatchInfos.setDiffBundleDex(true);
    FileUtils.writeStringToFile(tpatchInput.outPutJson, JSON.toJSONString(buildPatchInfos));
    // 删除临时的目录
    FileUtils.deleteDirectory(patchTmpDir);
    apkDiff.setBaseApkVersion(input.baseApkBo.getVersionName());
    apkDiff.setNewApkVersion(input.newApkBo.getVersionName());
    apkDiff.setBundleDiffResults(bundleDiffResults);
    boolean newApkFileExist = input.newApkBo.getApkFile().exists() && input.newApkBo.getApkFile().isFile();
    if (newApkFileExist) {
        apkDiff.setNewApkMd5(MD5Util.getFileMD5String(input.newApkBo.getApkFile()));
    }
    apkDiff.setFileName(input.newApkBo.getApkName());
    apkPatchInfos.setBaseApkVersion(input.baseApkBo.getVersionName());
    apkPatchInfos.setNewApkVersion(input.newApkBo.getVersionName());
    apkPatchInfos.setBundleDiffResults(diffPatchInfos);
    apkPatchInfos.setFileName(patchFile.getName());
    apkPatchInfos.setNewApkMd5(MD5Util.getFileMD5String(patchFile));
    FileUtils.writeStringToFile(tpatchFile.diffJson, JSON.toJSONString(apkDiff));
    FileUtils.writeStringToFile(tpatchFile.patchInfo, JSON.toJSONString(apkPatchInfos));
    FileUtils.copyFileToDirectory(tpatchFile.diffJson, tpatchInput.outPatchDir.getParentFile(), true);
    if (newApkFileExist) {
        FileUtils.copyFileToDirectory(input.newApkBo.getApkFile(), tpatchInput.outPatchDir.getParentFile(), true);
    }
    Profiler.release();
    logger.warning(Profiler.dump());
    return tpatchFile;
}
Also used : BundleBO(com.taobao.android.tpatch.model.BundleBO) DexPatchFile(com.taobao.android.outputs.DexPatchFile) PatchInfo(com.taobao.android.object.PatchInfo) TpatchInput(com.taobao.android.inputs.TpatchInput) IOException(java.io.IOException) ExecutorServicesHelper(com.taobao.android.task.ExecutorServicesHelper) File(java.io.File) DexPatchFile(com.taobao.android.outputs.DexPatchFile) PatchFile(com.taobao.android.outputs.PatchFile) BuildPatchInfos(com.taobao.android.object.BuildPatchInfos)

Example 7 with TpatchInput

use of com.taobao.android.inputs.TpatchInput in project atlas by alibaba.

the class DexPatchTool method createDexPatchFile.

private File createDexPatchFile(File outPatchDir, File patchTmpDir) throws IOException {
    File mainBundleFoder = new File(patchTmpDir, ((TpatchInput) input).mainBundleName);
    File mainBundleFile = new File(patchTmpDir, "lib" + ((TpatchInput) input).mainBundleName.replace(".", "_") + ".so");
    if (FileUtils.listFiles(mainBundleFoder, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE).size() > 0) {
        CommandUtils.exec(mainBundleFoder, "zip -r " + mainBundleFile.getAbsolutePath() + " . -x */ -x .*");
    }
    FileUtils.deleteDirectory(mainBundleFoder);
    // 再压缩各自的bundle
    File patchFile = null;
    patchFile = new File(outPatchDir, input.newApkBo.getVersionName() + "@" + input.baseApkBo.getVersionName() + ".tpatch");
    if (patchFile.exists()) {
        FileUtils.deleteQuietly(patchFile);
    }
    // zipBundle(patchTmpDir, patchFile);
    CommandUtils.exec(patchTmpDir, "zip -r " + patchFile.getAbsolutePath() + " . -x */ -x .*");
    FileUtils.deleteDirectory(patchTmpDir);
    return patchFile;
}
Also used : File(java.io.File) DexPatchFile(com.taobao.android.outputs.DexPatchFile) PatchFile(com.taobao.android.outputs.PatchFile) TpatchInput(com.taobao.android.inputs.TpatchInput)

Example 8 with TpatchInput

use of com.taobao.android.inputs.TpatchInput in project atlas by alibaba.

the class TPatchTool method getLastPatchFile.

protected File getLastPatchFile(String baseApkVersion, String productName, File outPatchDir) throws IOException {
    try {
        String httpUrl = ((TpatchInput) input).LAST_PATCH_URL + "baseVersion=" + baseApkVersion + "&productIdentifier=" + productName;
        String response = HttpClientUtils.getUrl(httpUrl);
        if (StringUtils.isBlank(response) || response.equals("\"\"")) {
            return null;
        }
        File downLoadFolder = new File(outPatchDir, "LastPatch");
        downLoadFolder.mkdirs();
        File downLoadFile = new File(downLoadFolder, "lastpatch.tpatch");
        String downLoadUrl = StringEscapeUtils.unescapeJava(response);
        downloadTPath(downLoadUrl.substring(1, downLoadUrl.length() - 1), downLoadFile);
        return downLoadFile;
    } catch (Exception e) {
        return null;
    }
}
Also used : TpatchInput(com.taobao.android.inputs.TpatchInput) TpatchFile(com.taobao.android.outputs.TpatchFile) ZipFile(java.util.zip.ZipFile) PatchFile(com.taobao.android.outputs.PatchFile) RecognitionException(org.antlr.runtime.RecognitionException) PatchException(com.taobao.android.differ.dex.PatchException)

Example 9 with TpatchInput

use of com.taobao.android.inputs.TpatchInput in project atlas by alibaba.

the class TPatchTool method createIncrementPatchFiles.

/**
 * create increment patch
 * file
 */
private BuildPatchInfos createIncrementPatchFiles(String productionName, File curTPatchFile, File targetDirectory, File newApkUnzipFolder, PatchInfo curPatchInfo, String patchHistoryUrl) throws IOException, PatchException {
    BuildPatchInfos historyBuildPatchInfos = null;
    String response = null;
    if (!StringUtils.isEmpty(patchHistoryUrl)) {
        String patchHisUrl = patchHistoryUrl + "?baseVersion=" + input.baseApkBo.getVersionName() + "&productIdentifier=" + productionName;
        try {
            response = HttpClientUtils.getUrl(patchHisUrl);
            historyBuildPatchInfos = JSON.parseObject(response, BuildPatchInfos.class);
        } catch (Throwable e) {
            historyBuildPatchInfos = null;
        }
    } else {
        File[] files = hisTpatchFolder.listFiles(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String filename) {
                return filename.startsWith("patchs-") && filename.endsWith(".json");
            }
        });
        if (files != null && files.length > 0) {
            historyBuildPatchInfos = mergeHisPatchInfo(files);
        }
    }
    if (historyBuildPatchInfos == null) {
        return new BuildPatchInfos();
    }
    Iterator<PatchInfo> patchInfos = historyBuildPatchInfos.getPatches().iterator();
    while (patchInfos.hasNext()) {
        PatchInfo patchInfo = patchInfos.next();
        if (!patchInfo.getTargetVersion().equals(input.baseApkBo.getVersionName())) {
            patchInfos.remove();
        }
    }
    Map<String, File> awbBundleMap = new HashMap<String, File>();
    for (ArtifactBundleInfo artifactBundleInfo : input.artifactBundleInfos) {
        String bundleFileSoName = "lib" + artifactBundleInfo.getPkgName().replace('.', '_') + ".so";
        File bundleFile = new File(newApkUnzipFolder, "lib" + "/" + "armeabi" + "/" + bundleFileSoName);
        File assetsBundleFile = new File(newApkUnzipFolder, "assets" + "/" + bundleFileSoName);
        if (bundleFile.exists()) {
            awbBundleMap.put(artifactBundleInfo.getArtifactId(), bundleFile);
        } else if (assetsBundleFile.exists()) {
            awbBundleMap.put(artifactBundleInfo.getArtifactId(), assetsBundleFile);
        }
    }
    if (((TpatchInput) input).splitDiffBundle != null) {
        for (Pair<BundleBO, BundleBO> bundle : ((TpatchInput) input).splitDiffBundle) {
            awbBundleMap.put(bundle.getSecond().getBundleName(), bundle.getSecond().getBundleFile());
        }
    }
    PatchFileBuilder patchFileBuilder = new PatchFileBuilder(historyBuildPatchInfos, curTPatchFile, curPatchInfo, awbBundleMap, targetDirectory, input.baseApkBo.getVersionName());
    patchFileBuilder.setNoPatchBundles(((TpatchInput) input).noPatchBundles);
    patchFileBuilder.setHistroyVersionList(((TpatchInput) input).versionList);
    return patchFileBuilder.createHistoryTPatches(input.diffBundleDex, logger);
}
Also used : BundleBO(com.taobao.android.tpatch.model.BundleBO) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TpatchInput(com.taobao.android.inputs.TpatchInput) TpatchFile(com.taobao.android.outputs.TpatchFile) ZipFile(java.util.zip.ZipFile) PatchFile(com.taobao.android.outputs.PatchFile) PatchFileBuilder(com.taobao.android.tpatch.builder.PatchFileBuilder)

Aggregations

TpatchInput (com.taobao.android.inputs.TpatchInput)9 PatchFile (com.taobao.android.outputs.PatchFile)7 ZipFile (java.util.zip.ZipFile)6 TpatchFile (com.taobao.android.outputs.TpatchFile)5 BundleBO (com.taobao.android.tpatch.model.BundleBO)4 PatchException (com.taobao.android.differ.dex.PatchException)2 DexPatchFile (com.taobao.android.outputs.DexPatchFile)2 ExecutorServicesHelper (com.taobao.android.task.ExecutorServicesHelper)2 File (java.io.File)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 RecognitionException (org.antlr.runtime.RecognitionException)2 Pair (com.android.utils.Pair)1 AwbBundle (com.taobao.android.builder.dependency.model.AwbBundle)1 DexPatchInput (com.taobao.android.inputs.DexPatchInput)1 HotPatchInput (com.taobao.android.inputs.HotPatchInput)1 BuildPatchInfos (com.taobao.android.object.BuildPatchInfos)1 PatchInfo (com.taobao.android.object.PatchInfo)1 PatchFileBuilder (com.taobao.android.tpatch.builder.PatchFileBuilder)1 UpdateInfo (com.taobao.update.UpdateInfo)1 IOException (java.io.IOException)1