Search in sources :

Example 1 with BuildPatchInfos

use of com.taobao.android.object.BuildPatchInfos in project atlas by alibaba.

the class TPatchTool method createIncrementPatchFiles.

/**
     * 生成增量的patch文件
     */
private BuildPatchInfos createIncrementPatchFiles(String productionName, File curTPatchFile, File targetDirectory, File newApkUnzipFolder, PatchInfo curPatchInfo, String patchHistoryUrl) throws IOException, PatchException {
    BuildPatchInfos historyBuildPatchInfos = null;
    if (!StringUtils.isEmpty(patchHistoryUrl)) {
        String patchHisUrl = patchHistoryUrl + "?baseVersion=" + baseApkVersion + "&productIdentifier=" + productionName;
        String response = HttpClientUtils.getUrl(patchHisUrl);
        historyBuildPatchInfos = JSON.parseObject(response, BuildPatchInfos.class);
    }
    Map<String, File> awbBundleMap = new HashMap<String, File>();
    for (ArtifactBundleInfo artifactBundleInfo : artifactBundleInfos) {
        String bundleFileSoName = "lib" + artifactBundleInfo.getPkgName().replace('.', '_') + ".so";
        File bundleFile = new File(newApkUnzipFolder, "lib" + File.separator + "armeabi" + File.separator + bundleFileSoName);
        if (bundleFile.exists()) {
            awbBundleMap.put(artifactBundleInfo.getArtifactId(), bundleFile);
        }
    }
    PatchFileBuilder patchFileBuilder = new PatchFileBuilder(historyBuildPatchInfos, curTPatchFile, curPatchInfo, awbBundleMap, targetDirectory, baseApkVersion);
    patchFileBuilder.setNoPatchBundles(noPatchBundles);
    return patchFileBuilder.createHistoryTPatches(diffBundleDex, logger);
}
Also used : ArtifactBundleInfo(com.taobao.android.object.ArtifactBundleInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) BuildPatchInfos(com.taobao.android.object.BuildPatchInfos) File(java.io.File) PatchFileBuilder(com.taobao.android.tpatch.builder.PatchFileBuilder)

Example 2 with BuildPatchInfos

use of com.taobao.android.object.BuildPatchInfos in project atlas by alibaba.

the class UpdateTest method test.

@Test
public void test() throws IOException {
    //        System.out.println(123);
    File file = new File(getClass().getClassLoader().getResource("patchs.json").getFile());
    String json = FileUtils.readFileToString(file);
    BuildPatchInfos patchInfos = JSON.parseObject(json, BuildPatchInfos.class);
    UpdateInfo updateInfo = new UpdateInfo();
    updateInfo.baseVersion = patchInfos.getBaseVersion();
    updateInfo.updateVersion = patchInfos.getPatches().get(0).getPatchVersion();
    PatchInfo patchInfo = patchInfos.getPatches().get(0);
    List<UpdateInfo.Item> items = new ArrayList<UpdateInfo.Item>();
    for (PatchBundleInfo patchBundleInfo : patchInfo.getBundles()) {
        UpdateInfo.Item item = new UpdateInfo.Item();
        items.add(item);
        item.dependency = patchBundleInfo.getDependency();
        item.isMainDex = patchBundleInfo.getMainBundle();
        item.name = patchBundleInfo.getPkgName();
        //            item.srcVersion = patchBundleInfo.getVersion();
        item.version = updateInfo.baseVersion + "@" + patchBundleInfo.getVersion();
    }
    updateInfo.updateBundles = items;
    System.out.println(updateInfo);
}
Also used : PatchBundleInfo(com.taobao.android.object.PatchBundleInfo) PatchInfo(com.taobao.android.object.PatchInfo) ArrayList(java.util.ArrayList) File(java.io.File) BuildPatchInfos(com.taobao.android.object.BuildPatchInfos) Test(org.junit.Test)

Example 3 with BuildPatchInfos

use of com.taobao.android.object.BuildPatchInfos in project atlas by alibaba.

the class TPatchTask method doTPatch.

@TaskAction
public void doTPatch() throws Exception {
    patchContext = getPatchContext();
    signingConfig = getSigningConfig();
    outPatchFolder = getOutPatchFolder();
    // 获取容器版本
    String baseApkVersion = patchContext.getBaseVersionName();
    String newApkVersion = patchContext.versionName;
    File baseApk = patchContext.getBaseApk();
    File newApk = patchContext.diffApkFile;
    boolean retainMainBundleRes = true;
    if (null == newApk || !newApk.exists()) {
        newApk = patchContext.newApk;
        retainMainBundleRes = false;
    }
    getLogger().info("BaseApk:" + baseApk + ",baseVersion:" + baseApkVersion + ",newApk:" + newApk + ",newApkVersion:" + newApkVersion);
    TPatchTool tPatchTool = new TPatchTool(baseApk, newApk, baseApkVersion, newApkVersion, patchContext.diffBundleDex);
    tPatchTool.setMainBundleName(patchContext.mainBundleName);
    if (StringUtils.isNotBlank(patchContext.excludeFiles)) {
        tPatchTool.setNotIncludeFiles(patchContext.excludeFiles.split(","));
    }
    tPatchTool.setRetainMainBundleRes(retainMainBundleRes);
    if (null != patchContext.artifactBundleInfos) {
        tPatchTool.setArtifactBundleInfos(patchContext.artifactBundleInfos);
    }
    tPatchTool.setBaseApkFileList(patchContext.getBaseApkFiles());
    tPatchTool.setNewApkFileList(patchContext.getNewApkFiles());
    tPatchTool.setLogger(getILogger());
    tPatchTool.setOnlyIncludeModifyBundle(patchContext.onlyBuildModifyAwb);
    tPatchTool.setNoPatchBundles(patchContext.notPatchBundles);
    ApkFileList apkFileList = AtlasBuildContext.finalApkFileList;
    try {
        tPatchTool.setDexcode(apkFileList.getMainBundle().get("classes.dex"));
        FileUtils.writeStringToFile(new File(getOutPatchFolder(), "tpatch-bundles.json"), JSON.toJSONString(patchContext.artifactBundleInfos));
        getLogger().info("start to do patch");
        tPatchTool.doPatch(outPatchFolder, true, new File(getOutPatchFolder(), "patchs.json"), StringUtils.isNotEmpty(patchContext.tpatchHistoryUrl), patchContext.tpatchHistoryUrl, patchContext.appSignName);
        getLogger().info("finish  do patch");
        File patchJson = new File(getOutPatchFolder(), "patchs.json");
        File updateJson = new File(getOutPatchFolder(), "update.json");
        String json = FileUtils.readFileToString(patchJson);
        BuildPatchInfos patchInfos = JSON.parseObject(json, BuildPatchInfos.class);
        UpdateInfo updateInfo = new UpdateInfo(patchInfos);
        FileUtils.writeStringToFile(updateJson, JSON.toJSONString(updateInfo, true));
    } catch (Exception e) {
        e.printStackTrace();
        throw new StopExecutionException(e.getMessage());
    }
    File baseVesrionApk = new File(patchContext.newApk.getParentFile(), patchContext.newApk.getName().replace(".apk", "-" + baseApkVersion + ".apk"));
    FileUtils.copyFile(patchContext.getBaseApk(), baseVesrionApk);
    if (patchContext.writeBuildInfo && StringUtils.isNotEmpty(patchContext.buildId)) {
        File buildFile = new File(getOutPatchFolder(), "build.txt");
        FileUtils.writeStringToFile(buildFile, patchContext.buildId + "," + patchContext.versionName + "," + apkFileList.getMainBundle().get("classes.dex"));
        if (buildFile != null && buildFile.exists()) {
            getLogger().debug("write build to apk!");
            BuildHelper.writeFileToApk(buildFile, baseVesrionApk, "assets/build.txt");
        }
        BuildHelper.reSign(baseVesrionApk, signingConfig);
    }
    FileUtils.forceDelete(patchContext.newApk);
}
Also used : StopExecutionException(org.gradle.api.tasks.StopExecutionException) ApkFileList(com.taobao.android.object.ApkFileList) File(java.io.File) TPatchTool(com.taobao.android.TPatchTool) BuildPatchInfos(com.taobao.android.object.BuildPatchInfos) UpdateInfo(com.taobao.android.builder.tools.update.UpdateInfo) DocumentException(org.dom4j.DocumentException) StopExecutionException(org.gradle.api.tasks.StopExecutionException) IOException(java.io.IOException) MtlBaseTaskAction(com.taobao.android.builder.tasks.manager.MtlBaseTaskAction) TaskAction(org.gradle.api.tasks.TaskAction)

Example 4 with BuildPatchInfos

use of com.taobao.android.object.BuildPatchInfos in project atlas by alibaba.

the class TPatchTool method doPatch.

/**
     * 生成patch文件
     *
     * @param outPatchDir        生成patch文件的目录
     * @param createPatchJson
     * @param outPatchJson
     * @param createHistoryPatch
     * @param patchHistoryUrl
     * @param productName
     * @return 得到最后的patch的地址
     */
public File doPatch(File outPatchDir, boolean createPatchJson, File outPatchJson, boolean createHistoryPatch, String patchHistoryUrl, String productName) throws Exception {
    isTpatch = true;
    File lastPatchFile = null;
    pName = productName;
    lastPatchFile = getLastPatchFile(baseApkVersion, productName, outPatchDir);
    PatchUtils.getTpatchClassDef(lastPatchFile, bundleClassMap);
    final File diffTxtFile = new File(outPatchDir, "tpatch-diff.txt");
    final File patchTmpDir = new File(outPatchDir, "tpatch-tmp");
    File mainDiffFolder = new File(patchTmpDir, mainBundleName);
    FileUtils.deleteDirectory(patchTmpDir);
    FileUtils.deleteDirectory(mainDiffFolder);
    patchTmpDir.mkdirs();
    mainDiffFolder.mkdirs();
    // 解压apk
    File unzipFolder = unzipApk(outPatchDir);
    final File newApkUnzipFolder = new File(unzipFolder, NEW_APK_UNZIP_NAME);
    final File baseApkUnzipFolder = new File(unzipFolder, BASE_APK_UNZIP_NAME);
    // 得到主bundle的dex diff文件
    File mianDiffDestDex = new File(mainDiffFolder, DEX_NAME);
    File tmpDexFile = new File(patchTmpDir, mainBundleName + "-dex");
    createBundleDexPatch(newApkUnzipFolder, baseApkUnzipFolder, mianDiffDestDex, tmpDexFile, diffTxtFile);
    // 是否保留主bundle的资源文件
    if (isRetainMainBundleRes()) {
        copyMainBundleResources(newApkUnzipFolder, baseApkUnzipFolder, new File(patchTmpDir, mainBundleName));
    }
    ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper();
    String taskName = "diffBundleTask";
    // 判断主bundle的so和awb的插件
    Collection<File> soFiles = FileUtils.listFiles(newApkUnzipFolder, new String[] { "so" }, true);
    for (final File soFile : soFiles) {
        final String relativePath = PathUtils.toRelative(newApkUnzipFolder, soFile.getAbsolutePath());
        if (null != notIncludeFiles && pathMatcher.match(notIncludeFiles, relativePath)) {
            continue;
        }
        executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                File baseSoFile = new File(baseApkUnzipFolder, relativePath);
                if (PatchUtils.isBundleFile(soFile)) {
                    // 如果是bundle文件
                    processBundleFiles(soFile, baseSoFile, patchTmpDir, diffTxtFile);
                } else {
                    File destFile = new File(patchTmpDir, mainBundleName + File.separator + relativePath);
                    if (isFileModify(soFile, baseSoFile)) {
                        FileUtils.copyFile(soFile, destFile);
                    }
                }
                return true;
            }
        });
    }
    executorServicesHelper.waitTaskCompleted(taskName);
    executorServicesHelper.stop();
    // 压缩patch文件夹,得到tpatch文件
    File patchFile = createTPatchFile(outPatchDir, patchTmpDir);
    PatchInfo curPatchInfo = createBasePatchInfo(patchFile.getName());
    BuildPatchInfos buildPatchInfos = null;
    // 生成多版本的tpatch文件
    buildPatchInfos = createIncrementPatchFiles(productName, patchFile, outPatchDir, newApkUnzipFolder, curPatchInfo, patchHistoryUrl);
    buildPatchInfos.setDexcode(dexcode);
    if (createPatchJson) {
        FileUtils.writeStringToFile(outPatchJson, JSON.toJSONString(buildPatchInfos));
    }
    // 删除临时的目录
    FileUtils.deleteDirectory(patchTmpDir);
    //        FileUtils.deleteDirectory(unzipFolder);
    return patchFile;
}
Also used : ExecutorServicesHelper(com.taobao.android.task.ExecutorServicesHelper) PatchInfo(com.taobao.android.object.PatchInfo) File(java.io.File) BuildPatchInfos(com.taobao.android.object.BuildPatchInfos) RecognitionException(org.antlr.runtime.RecognitionException) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException)

Example 5 with BuildPatchInfos

use of com.taobao.android.object.BuildPatchInfos in project atlas by alibaba.

the class PatchFileBuilder method createHistoryTPatches.

/**
     * 创建历史版本的tpatch
     */
public BuildPatchInfos createHistoryTPatches(boolean diffBundleDex, final ILogger logger) throws PatchException {
    final BuildPatchInfos buildPatchInfos = new BuildPatchInfos();
    buildPatchInfos.setBaseVersion(baseVersion);
    List<PatchInfo> patchInfos = historyBuildPatchInfos.getPatches();
    String taskName = "CreateHisPatch";
    ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper();
    for (final PatchInfo patchInfo : patchInfos) {
        if (patchInfo.getPatchVersion().split("\\.").length > 3 && TPatchTool.pName.equals("taobao4android")) {
            continue;
        }
        executorServicesHelper.submitTask(taskName, new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                if (null != logger) {
                    logger.info("[CreateHisPatch]" + patchInfo.getPatchVersion() + "....");
                }
                try {
                    hisPatchInfos.put(patchInfo.getPatchVersion(), patchInfo);
                    PatchInfo newPatchInfo = createHisTPatch(patchInfo.getPatchVersion(), logger);
                    buildPatchInfos.getPatches().add(newPatchInfo);
                } catch (IOException e) {
                    throw new PatchException(e.getMessage(), e);
                }
                return true;
            }
        });
    }
    try {
        executorServicesHelper.waitTaskCompleted(taskName);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    executorServicesHelper.stop();
    buildPatchInfos.getPatches().add(currentBuildPatchInfo);
    buildPatchInfos.setDiffBundleDex(diffBundleDex);
    return buildPatchInfos;
}
Also used : PatchInfo(com.taobao.android.object.PatchInfo) PatchException(com.taobao.android.differ.dex.PatchException) ExecutionException(java.util.concurrent.ExecutionException) ExecutorServicesHelper(com.taobao.android.task.ExecutorServicesHelper) PatchException(com.taobao.android.differ.dex.PatchException) ExecutionException(java.util.concurrent.ExecutionException) BuildPatchInfos(com.taobao.android.object.BuildPatchInfos)

Aggregations

BuildPatchInfos (com.taobao.android.object.BuildPatchInfos)5 File (java.io.File)4 PatchInfo (com.taobao.android.object.PatchInfo)3 PatchException (com.taobao.android.differ.dex.PatchException)2 ExecutorServicesHelper (com.taobao.android.task.ExecutorServicesHelper)2 IOException (java.io.IOException)2 TPatchTool (com.taobao.android.TPatchTool)1 MtlBaseTaskAction (com.taobao.android.builder.tasks.manager.MtlBaseTaskAction)1 UpdateInfo (com.taobao.android.builder.tools.update.UpdateInfo)1 ApkFileList (com.taobao.android.object.ApkFileList)1 ArtifactBundleInfo (com.taobao.android.object.ArtifactBundleInfo)1 PatchBundleInfo (com.taobao.android.object.PatchBundleInfo)1 PatchFileBuilder (com.taobao.android.tpatch.builder.PatchFileBuilder)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ExecutionException (java.util.concurrent.ExecutionException)1 RecognitionException (org.antlr.runtime.RecognitionException)1 DocumentException (org.dom4j.DocumentException)1 StopExecutionException (org.gradle.api.tasks.StopExecutionException)1