Search in sources :

Example 6 with DexMerger

use of com.android.dx.merge.DexMerger in project HL4A by HL4A.

the class 基本加载器 method defineClass.

public Class<?> defineClass(String name, byte[] data) {
    try {
        DexOptions dexOptions = new DexOptions();
        com.android.dx.dex.file.DexFile dexFile = new com.android.dx.dex.file.DexFile(dexOptions);
        DirectClassFile classFile = new DirectClassFile(data, name.replace('.', '/') + ".class", true);
        classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);
        classFile.getMagic();
        dexFile.add(CfTranslator.translate(classFile, null, new CfOptions(), dexOptions, dexFile));
        Dex dex = new Dex(dexFile.toDex(null, false));
        if (oldDex != null) {
            dex = new DexMerger(dex, oldDex, CollisionPolicy.KEEP_FIRST).merge();
        }
        return loadClass(dex, name);
    } catch (IOException | ClassNotFoundException e) {
        throw new FatalLoadingException(e);
    }
}
Also used : DexMerger(com.android.dx.merge.DexMerger) DexOptions(com.android.dx.dex.DexOptions) IOException(java.io.IOException) DirectClassFile(com.android.dx.cf.direct.DirectClassFile) Dex(com.android.dex.Dex) CfOptions(com.android.dx.dex.cf.CfOptions)

Example 7 with DexMerger

use of com.android.dx.merge.DexMerger in project atlas by alibaba.

the class PackageAwbsTask method createAwbPackages.

/**
 * Directory of so
 */
@TaskAction
void createAwbPackages() throws ExecutionException, InterruptedException, IOException {
    File awbApkOutputDir = appVariantContext.getAwbApkOutputDir();
    FileUtils.cleanOutputDir(awbApkOutputDir);
    AtlasDependencyTree atlasDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());
    if (null == atlasDependencyTree) {
        return;
    }
    ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName, getLogger(), 0);
    List<Runnable> runnables = new ArrayList<>();
    final AtomicLong dexTotalTime = new AtomicLong(0);
    final AtomicLong packageTotalTime = new AtomicLong(0);
    final Map<String, Long[]> monitors = new HashMap<String, Long[]>();
    long startTime = System.currentTimeMillis();
    for (final AwbBundle awbBundle : atlasDependencyTree.getAwbBundles()) {
        if (awbBundle.isMBundle) {
            continue;
        }
        runnables.add(() -> {
            try {
                long start = System.currentTimeMillis();
                // create dex
                File dexOutputFile = appVariantContext.getAwbDexOutput(awbBundle.getName());
                long endDex = System.currentTimeMillis();
                // PACKAGE APP:
                File resourceFile = null;
                if (appVariantContext.getScope().useResourceShrinker()) {
                    resourceFile = appVariantOutputContext.getAwbCompressResourcePackageOutputFile(awbBundle);
                } else {
                    resourceFile = appVariantOutputContext.getAwbAndroidResourcesMap().get(awbBundle.getName()).getPackageOutputFile();
                }
                if (!resourceFile.exists()) {
                    resourceFile = appVariantOutputContext.getAwbAndroidResourcesMap().get(awbBundle.getName()).getPackageOutputFile();
                }
                Set<File> dexFolders = new HashSet<File>();
                dexFolders.add(dexOutputFile);
                Set<File> jniFolders = Sets.newHashSet();
                if (appVariantOutputContext.getAwbJniFolder(awbBundle) != null && appVariantOutputContext.getAwbJniFolder(awbBundle).exists()) {
                    jniFolders.add(appVariantOutputContext.getAwbJniFolder(awbBundle));
                }
                Set<File> javaResourcesLocations = Sets.newHashSet();
                if (appVariantContext.getAtlasExtension().getTBuildConfig().isIncremental() && awbBundle.getAllLibraryAars().size() > 1) {
                    File baseAwb = appVariantOutputContext.getVariantContext().apContext.getBaseAwb(awbBundle.getAwbSoName());
                    if (baseAwb != null) {
                        ZipFile files = new ZipFile(baseAwb);
                        ZipEntry entry = files.getEntry("classes.dex");
                        if (entry == null) {
                            throw new DexException("Expected classes.dex in " + baseAwb);
                        }
                        File file = new File(dexOutputFile, "classes.dex");
                        com.android.dex.Dex[] dexes = new com.android.dex.Dex[2];
                        dexes[0] = new com.android.dex.Dex(file);
                        dexes[1] = new com.android.dex.Dex(files.getInputStream(entry));
                        com.android.dex.Dex merged = new DexMerger(dexes, CollisionPolicy.KEEP_FIRST, new DxContext()).merge();
                        merged.writeTo(file);
                        javaResourcesLocations.add(baseAwb);
                    }
                }
                if (appVariantContext.getAtlasExtension().getTBuildConfig().getMergeAwbJavaRes()) {
                    javaResourcesLocations.add(new File(appVariantOutputContext.getAwbJavaResFolder(awbBundle), "res.jar"));
                }
                AwbApkPackageTask awbApkPackageTask = new AwbApkPackageTask(getProject().files(resourceFile), appVariantContext, awbBundle, appVariantOutputContext, getProject().files(dexFolders), getProject().files(javaResourcesLocations), getProject().files(appVariantOutputContext.getVariantContext().getMergeAssets(awbBundle)), getProject().files(jniFolders), getProject().files(awbBundle.getMergedManifest()), getBuilder(), config.getMinSdkVersion().getApiLevel(), getName());
                File awbFile = awbApkPackageTask.doFullTaskAction();
                bundles.put(awbBundle, awbFile);
                // //                        //TODO 2.3
                // AtlasBuildContext.androidBuilderMap.get(getProject())
                // .oldPackageApk(resourceFile.getAbsolutePath(),
                // dexFolders,
                // javaResourcesLocations,
                // jniFolders,
                // null,
                // getAbiFilters(),
                // config.getBuildType().isJniDebuggable(),
                // null,
                // getOutputFile(awbBundle),
                // config.getMinSdkVersion().getApiLevel(),
                // new com.google.common.base.Predicate<String>() {
                // @Override
                // public boolean apply(@Nullable String s) {
                // return false;
                // }
                // });
                long endPackage = System.currentTimeMillis();
                dexTotalTime.addAndGet(endDex - start);
                packageTotalTime.addAndGet(endPackage - endDex);
                monitors.put(awbBundle.getName(), new Long[] { endDex - start, endPackage - endDex });
            } catch (Throwable e) {
                // e.printStackTrace();
                throw new GradleException("package " + awbBundle.getName() + " failed", e);
            }
        });
    }
    executorServicesHelper.execute(runnables);
    getLogger().info(">>>>> packageAwbs >>>>>>>>>>>>");
    FileLogger fileLogger = FileLogger.getInstance("packageAwbs");
    fileLogger.log("totalTime is " + (System.currentTimeMillis() - startTime));
    fileLogger.log("dexTotalTime is " + dexTotalTime);
    fileLogger.log("packageTotalTime is " + packageTotalTime);
    String format = "[packageawb]  bundle:%50s  dexTime: %10d  packageTime: %10d ";
    for (String bundle : monitors.keySet()) {
        Long[] value = monitors.get(bundle);
        fileLogger.log(String.format(format, bundle, value[0], value[1]));
    }
    getLogger().info(">>>>> packageAwbs >>>>>>>>>>>>");
    PackageApplication packageApplication = appVariantContext.getScope().getPackageApplicationTask().get(new TaskContainerAdaptor(appVariantContext.getScope().getGlobalScope().getProject().getTasks()));
    packageApplication.doFirst(new FirstApkAction(appVariantOutputContext));
    packageApplication.doLast(new LastApkAction());
}
Also used : DexException(com.android.dex.DexException) ZipEntry(java.util.zip.ZipEntry) DexMerger(com.android.dx.merge.DexMerger) TaskContainerAdaptor(com.android.build.gradle.internal.TaskContainerAdaptor) ExecutorServicesHelper(com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper) AwbBundle(com.taobao.android.builder.dependency.model.AwbBundle) AtlasDependencyTree(com.taobao.android.builder.dependency.AtlasDependencyTree) LastApkAction(com.taobao.android.builder.tasks.app.bundle.actions.LastApkAction) DxContext(com.android.dx.command.dexer.DxContext) AtomicLong(java.util.concurrent.atomic.AtomicLong) ZipFile(java.util.zip.ZipFile) FirstApkAction(com.taobao.android.builder.tasks.app.bundle.actions.FirstApkAction) GradleException(org.gradle.api.GradleException) AtomicLong(java.util.concurrent.atomic.AtomicLong) FileLogger(com.taobao.android.builder.tools.log.FileLogger) PackageApplication(com.android.build.gradle.tasks.PackageApplication) ZipFile(java.util.zip.ZipFile) File(java.io.File) MtlBaseTaskAction(com.taobao.android.builder.tasks.manager.MtlBaseTaskAction) TaskAction(org.gradle.api.tasks.TaskAction)

Example 8 with DexMerger

use of com.android.dx.merge.DexMerger in project atlas by alibaba.

the class AtlasBuilder method convertByteCode.

// dexMain entrance
public void convertByteCode(Collection<File> inputs, File outDexFolder, boolean multidex, File mainDexList, DexOptions dexOptions, ProcessOutputHandler processOutputHandler, boolean awb) throws IOException, InterruptedException, ProcessException {
    boolean fastMultiDex = false;
    Profiler.start();
    if (atlasExtension.getTBuildConfig().isDexCacheEnabled() && inputs.size() > 0) {
        Profiler.enter("jar2dex");
        List<Dex> dexs = new ArrayList<>();
        Map<File, Dex> fileDexMap = new HashMap<>();
        // Do dexMerge
        File tmpDir = new File(outDexFolder, "tmp");
        tmpDir.mkdirs();
        long startTime = System.currentTimeMillis();
        List<File> outputs = new ArrayList<>();
        for (File input : inputs) {
            logger.warning("Dex input File:%s", input.getAbsolutePath());
            final File dexDir = getDexOutputDir(input, tmpDir, outputs);
            dexDir.mkdirs();
            preDexLibrary(input, dexDir, multidex, dexOptions, processOutputHandler);
            outputs.add(dexDir);
        }
        for (File dexDir : outputs) {
            Collection<File> files = FileUtils.listFiles(dexDir, new String[] { "dex" }, true);
            for (File dexFile : files) {
                if (dexFile.exists() && dexFile.length() > 0) {
                    Dex dex = new Dex(dexFile);
                    dexs.add(dex);
                    fileDexMap.put(dexFile, dex);
                }
            }
        }
        Profiler.release();
        long endDexTime = System.currentTimeMillis();
        Profiler.enter("dexmerge");
        if (dexs.size() > 0) {
            if (multidex && !awb) {
                throw new GradleException("can't support~");
            } else {
                DexMerger dexMerger = new DexMerger(dexs.toArray(new Dex[0]), CollisionPolicy.KEEP_FIRST, new DxContext());
                Dex dex = dexMerger.merge();
                File dexFile = new File(outDexFolder, "classes.dex");
                dex.writeTo(dexFile);
                if (!dexFile.exists()) {
                    sLogger.error("dexmerge failed, not dex file found , inputs : " + dexs.size());
                }
            }
        } else {
            sLogger.error("no dex found to  " + outDexFolder.getAbsolutePath());
        }
        Profiler.release();
        FileUtils.deleteDirectory(tmpDir);
        long finishTime = System.currentTimeMillis();
        sLogger.info("[mtldex] dex consume {} , dexmerge consume {}", endDexTime - startTime, finishTime - endDexTime);
    }
    Profiler.release();
    if (fastMultiDex) {
        sLogger.error("[mtldex] main dex consume {} ", Profiler.dump());
    }
}
Also used : DexMerger(com.android.dx.merge.DexMerger) DxContext(com.android.dx.command.dexer.DxContext) Dex(com.android.dex.Dex) GradleException(org.gradle.api.GradleException) File(java.io.File)

Example 9 with DexMerger

use of com.android.dx.merge.DexMerger in project atlas by alibaba.

the class FastMultiDexer method mergeDex.

private void mergeDex(File outDexFolder, List<Dex> tmpList, int index, Dex[] mergedList) throws IOException {
    DexMerger dexMerger = new DexMerger(tmpList.toArray(new Dex[0]), CollisionPolicy.KEEP_FIRST, new DxContext());
    Dex dex = dexMerger.merge();
    mergedList[index] = dex;
    String name = "classes" + (0 == index ? "" : String.valueOf(index + 1)) + ".dex";
    File dexFile = new File(outDexFolder, name);
    dex.writeTo(dexFile);
}
Also used : DxContext(com.android.dx.command.dexer.DxContext) Dex(com.android.dex.Dex) DexMerger(com.android.dx.merge.DexMerger) File(java.io.File)

Aggregations

DexMerger (com.android.dx.merge.DexMerger)9 Dex (com.android.dex.Dex)8 DxContext (com.android.dx.command.dexer.DxContext)3 File (java.io.File)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 ArrayList (java.util.ArrayList)2 GradleException (org.gradle.api.GradleException)2 TaskContainerAdaptor (com.android.build.gradle.internal.TaskContainerAdaptor)1 PackageApplication (com.android.build.gradle.tasks.PackageApplication)1 DexException (com.android.dex.DexException)1 DirectClassFile (com.android.dx.cf.direct.DirectClassFile)1 DexOptions (com.android.dx.dex.DexOptions)1 CfOptions (com.android.dx.dex.cf.CfOptions)1 AtlasDependencyTree (com.taobao.android.builder.dependency.AtlasDependencyTree)1 AwbBundle (com.taobao.android.builder.dependency.model.AwbBundle)1 FirstApkAction (com.taobao.android.builder.tasks.app.bundle.actions.FirstApkAction)1 LastApkAction (com.taobao.android.builder.tasks.app.bundle.actions.LastApkAction)1 MtlBaseTaskAction (com.taobao.android.builder.tasks.manager.MtlBaseTaskAction)1 ExecutorServicesHelper (com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper)1 FileLogger (com.taobao.android.builder.tools.log.FileLogger)1