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);
}
}
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());
}
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());
}
}
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);
}
Aggregations