Search in sources :

Example 1 with PatchInfo

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

the class TPatchTool method createBasePatchInfo.

/**
     * 获取基准patch包的patchInfo对象
     *
     * @param fileName
     * @return
     */
public PatchInfo createBasePatchInfo(String fileName) {
    PatchInfo patchInfo = new PatchInfo();
    patchInfo.setPatchVersion(newApkVersion);
    patchInfo.setTargetVersion(baseApkVersion);
    patchInfo.setFileName(fileName);
    for (ArtifactBundleInfo artifactBundleInfo : artifactBundleInfos) {
        if (artifactBundleInfo.getMainBundle()) {
            if (DiffType.MODIFY.equals(artifactBundleInfo.getDiffType()) || hasMainBundle) {
                PatchBundleInfo patchBundleInfo = new PatchBundleInfo();
                patchBundleInfo.setNewBundle(DiffType.ADD.equals(artifactBundleInfo.getDiffType()));
                patchBundleInfo.setMainBundle(true);
                patchBundleInfo.setVersion(artifactBundleInfo.getVersion());
                patchBundleInfo.setName(mainBundleName);
                patchBundleInfo.setApplicationName(artifactBundleInfo.getApplicationName());
                patchBundleInfo.setArtifactId(artifactBundleInfo.getArtifactId());
                patchBundleInfo.setPkgName(artifactBundleInfo.getPkgName());
                patchBundleInfo.setDependency(artifactBundleInfo.getDependency());
                //                    patchBundleInfo.setBaseVersion(artifactBundleInfo.getBaseVersion());
                patchInfo.getBundles().add(patchBundleInfo);
                continue;
            }
        } else if (DiffType.MODIFY.equals(artifactBundleInfo.getDiffType()) || DiffType.ADD.equals(artifactBundleInfo.getDiffType())) {
            PatchBundleInfo patchBundleInfo = new PatchBundleInfo();
            patchBundleInfo.setNewBundle(DiffType.ADD.equals(artifactBundleInfo.getDiffType()));
            patchBundleInfo.setMainBundle(false);
            patchBundleInfo.setVersion(artifactBundleInfo.getVersion());
            patchBundleInfo.setName(artifactBundleInfo.getName());
            patchBundleInfo.setApplicationName(artifactBundleInfo.getApplicationName());
            patchBundleInfo.setArtifactId(artifactBundleInfo.getArtifactId());
            patchBundleInfo.setPkgName(artifactBundleInfo.getPkgName());
            patchBundleInfo.setDependency(artifactBundleInfo.getDependency());
            //                patchBundleInfo.setBaseVersion(artifactBundleInfo.getBaseVersion());
            patchInfo.getBundles().add(patchBundleInfo);
        }
    }
    return patchInfo;
}
Also used : PatchBundleInfo(com.taobao.android.object.PatchBundleInfo) ArtifactBundleInfo(com.taobao.android.object.ArtifactBundleInfo) PatchInfo(com.taobao.android.object.PatchInfo)

Example 2 with PatchInfo

use of com.taobao.android.object.PatchInfo 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 PatchInfo

use of com.taobao.android.object.PatchInfo 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 4 with PatchInfo

use of com.taobao.android.object.PatchInfo 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)

Example 5 with PatchInfo

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

the class PatchFileBuilder method processBundlePatch.

/**
     * 处理各自bundle的patch文件
     *
     * @param hisPatchInfo
     * @param bundlePatchs
     */
private PatchInfo processBundlePatch(PatchInfo hisPatchInfo, List<BundlePatch> bundlePatchs, File curTPatchUnzipFolder) throws IOException, PatchException {
    String patchName = "patch-" + currentBuildPatchInfo.getPatchVersion() + "@" + hisPatchInfo.getPatchVersion();
    PatchInfo patchInfo = new PatchInfo();
    patchInfo.setFileName(patchName + ".tpatch");
    patchInfo.setTargetVersion(hisPatchInfo.getPatchVersion());
    patchInfo.setPatchVersion(currentBuildPatchInfo.getPatchVersion());
    File hisTPatchFile = new File(tPatchTmpFolder, hisPatchInfo.getPatchVersion() + "-download.tpatch");
    File hisTPatchUnzipFolder = new File(tPatchTmpFolder, hisPatchInfo.getPatchVersion());
    File destTPathTmpFolder = new File(tPatchTmpFolder, patchName);
    if (!destTPathTmpFolder.exists()) {
        destTPathTmpFolder.mkdirs();
    }
    for (BundlePatch bundlePatch : bundlePatchs) {
        boolean addToPatch = true;
        String bundleName = "lib" + bundlePatch.pkgName.replace('.', '_');
        if (bundlePatch.mainBundle) {
            continue;
        } else if (noPatchBundles.contains(bundlePatch.pkgName)) {
            File currentBundle = new File(curTPatchUnzipFolder, "lib" + bundlePatch.pkgName.replace(".", "_") + ".so");
            if (!currentBundle.exists()) {
                continue;
            }
            FileUtils.copyFileToDirectory(currentBundle, destTPathTmpFolder);
            PatchBundleInfo patchBundleInfo = new PatchBundleInfo();
            patchBundleInfo.setApplicationName(bundlePatch.applicationName);
            patchBundleInfo.setArtifactId(bundlePatch.artifactId);
            patchBundleInfo.setMainBundle(false);
            patchBundleInfo.setNewBundle(bundlePatch.newBundle);
            patchBundleInfo.setName(bundleName);
            patchBundleInfo.setPkgName(bundlePatch.pkgName);
            patchBundleInfo.setVersion(bundlePatch.version);
            patchBundleInfo.setBaseVersion(bundlePatch.baseVersion);
            patchBundleInfo.setDependency(bundlePatch.dependency);
            patchInfo.getBundles().add(patchBundleInfo);
            continue;
        }
        File curBundleFolder = new File(curTPatchUnzipFolder, bundleName);
        File bundleDestFolder = new File(destTPathTmpFolder, bundleName);
        PatchBundleInfo patchBundleInfo = new PatchBundleInfo();
        patchBundleInfo.setApplicationName(bundlePatch.applicationName);
        patchBundleInfo.setArtifactId(bundlePatch.artifactId);
        patchBundleInfo.setMainBundle(false);
        patchBundleInfo.setNewBundle(bundlePatch.newBundle);
        patchBundleInfo.setName(bundleName);
        patchBundleInfo.setPkgName(bundlePatch.pkgName);
        patchBundleInfo.setVersion(bundlePatch.version);
        patchBundleInfo.setBaseVersion(bundlePatch.baseVersion);
        patchBundleInfo.setDependency(bundlePatch.dependency);
        switch(bundlePatch.bundlePolicy) {
            case ADD:
                bundleDestFolder.mkdirs();
                FileUtils.copyDirectory(curBundleFolder, bundleDestFolder);
                break;
            case REMOVE:
                addToPatch = false;
                // donothing
                break;
            case // donothing
            ROLLBACK:
                break;
            case MERGE:
                downloadTPathAndUnzip(hisPatchInfo.getDownloadUrl(), hisTPatchFile, hisTPatchUnzipFolder);
                File hisBundleFolder = new File(hisTPatchUnzipFolder, bundleName);
                if (!hisBundleFolder.exists()) {
                    //如果历史的文件不存在,就直接覆盖
                    throw new PatchException("The bundle:" + bundleName + " does not existed in tpatch:" + hisPatchInfo.getDownloadUrl());
                //                        bundleDestFolder.mkdirs();
                //                        FileUtils.copyDirectory(curBundleFolder, bundleDestFolder);
                } else {
                    File fullAwbFile = awbMaps.get(bundlePatch.artifactId);
                    copyDiffFiles(fullAwbFile, curBundleFolder, hisBundleFolder, bundleDestFolder);
                    if (!bundleDestFolder.exists() || bundleDestFolder.listFiles().length == 0) {
                        addToPatch = false;
                    }
                }
                break;
        }
        if (addToPatch) {
            patchInfo.getBundles().add(patchBundleInfo);
        }
    }
    return patchInfo;
}
Also used : PatchBundleInfo(com.taobao.android.object.PatchBundleInfo) PatchInfo(com.taobao.android.object.PatchInfo) PatchException(com.taobao.android.differ.dex.PatchException)

Aggregations

PatchInfo (com.taobao.android.object.PatchInfo)6 PatchBundleInfo (com.taobao.android.object.PatchBundleInfo)4 PatchException (com.taobao.android.differ.dex.PatchException)3 BuildPatchInfos (com.taobao.android.object.BuildPatchInfos)3 ExecutorServicesHelper (com.taobao.android.task.ExecutorServicesHelper)2 File (java.io.File)2 ArtifactBundleInfo (com.taobao.android.object.ArtifactBundleInfo)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 ExecutionException (java.util.concurrent.ExecutionException)1 RecognitionException (org.antlr.runtime.RecognitionException)1 Test (org.junit.Test)1