use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.
the class ApkPatch method buildPrepareClass.
private static Set<String> buildPrepareClass(File smaliDir, List<File> newFiles, DexDiffInfo info) throws PatchException {
Set<DexBackedClassDef> classes = Sets.newHashSet();
classes = SmaliDiffUtils.scanClasses(smaliDir, newFiles);
ArrayList<String> methods = new ArrayList<String>();
{
Set<DexBackedMethod> tempSet = info.getModifiedMethods();
for (DexBackedMethod methodRef : tempSet) {
String template = methodRef.getDefiningClass() + "->" + methodRef.getName();
methods.add(template);
System.out.println("template: " + template);
if (superClasses.containsKey(methodRef.getDefiningClass())) {
ArrayList<String> derivedClasses = superClasses.get(methodRef.getDefiningClass());
for (int i = 0; i < derivedClasses.size(); i++) {
template = derivedClasses.get(i) + "->" + methodRef.getName();
System.out.println("template: " + template);
methods.add(template);
}
}
}
}
Set<String> prepareClasses = new HashSet<String>();
try {
final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
for (DexBackedClassDef classDef : classes) {
currentClassType = null;
String className = TypeGenUtil.newType(classDef.getType());
// baksmali.disassembleClass(classDef, outFileNameHandler, options);
File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
if (!smaliFile.exists()) {
continue;
}
//增加class注解到prepare
getClassAnnotaionPrepareClasses(classDef, prepareClasses, info);
BufferedReader br = new BufferedReader(new FileReader(smaliFile));
// 一次读入一行,直到读入null为文件结束
String data = br.readLine();
while (data != null) {
boolean find = false;
for (String m : methods) {
if (data.contains(m)) {
find = true;
break;
}
}
if (find) {
prepareClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));
System.out.println("prepare class: " + className);
break;
}
// 接着读下一行
data = br.readLine();
}
br.close();
}
} catch (Exception e) {
throw new PatchException(e);
}
for (DexBackedMethod method : info.getModifiedMethods()) {
prepareClasses.add(method.getDefiningClass().substring(1, method.getDefiningClass().length() - 1).replace("/", "."));
}
// getMethodAnnotaionPrepareClasses(info,prepareClasses);
return prepareClasses;
}
use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.
the class ApkPatch method doPatch.
public File doPatch() throws PatchException {
try {
File aptchFolder = new File(out, name);
File smaliDir = new File(aptchFolder, "smali");
if (!smaliDir.exists()) {
smaliDir.mkdirs();
}
try {
FileUtils.cleanDirectory(smaliDir);
} catch (IOException e) {
throw new RuntimeException(e);
}
File dexFile = new File(aptchFolder, "diff.dex");
if (dexFile.exists() && !dexFile.delete()) {
throw new RuntimeException("diff.dex can't be removed.");
}
File outFile = new File(aptchFolder, "diff" + SUFFIX);
if (outFile.exists() && !outFile.delete()) {
throw new RuntimeException("diff" + SUFFIX + " can't be removed.");
}
currentTimeStamp = System.currentTimeMillis();
DexDiffer dexDiffer = new DexDiffer(baseFiles, newFiles, 19);
// 创建白名单过滤类
if ((this.filterPath != null) && !(this.filterPath.equals(""))) {
dexDiffer.createFilter(this.filterPath);
}
//diff
DexDiffInfo info = dexDiffer.doDiff();
dexDiffer.setDexDiffFilter(new AndFixFilterImpl(info));
//diffFilter
dexDiffer.dexFilter();
info.update();
//写json
if (null != diffFile && null != diffJsonFile) {
info.writeToFile(name, diffFile, diffJsonFile);
}
//生成dex
classes = SmaliDiffUtils.buildCode(smaliDir, dexFile, info);
if (null == classes || classes.size() <= 0) {
return null;
}
//是否修改dex
if (APatchTool.debug) {
PatchMethodTool.modifyMethod(dexFile.getAbsolutePath(), dexFile.getAbsolutePath(), true);
}
File smaliDir2 = new File(aptchFolder, "smali2");
if (!smaliDir2.exists()) {
smaliDir2.mkdirs();
}
try {
FileUtils.cleanDirectory(smaliDir2);
} catch (IOException e) {
throw new RuntimeException(e);
}
prepareClasses = buildPrepareClass(smaliDir2, newFiles, info);
DexDiffInfo.release();
build(outFile, dexFile);
File file = release(aptchFolder, dexFile, outFile);
release();
return file;
} catch (Exception e) {
throw new PatchException(e);
}
}
use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.
the class APatchTool method processBundleFiles.
/**
* 生成bundle的apatch文件
*
* @param newBundleFile
* @param baseBundleFile
* @param patchTmpDir
* @return
*/
private List<File> processBundleFiles(File newBundleFile, File baseBundleFile, File patchTmpDir, File diffFile, File diffJsonFile) throws PatchException, IOException, RecognitionException {
String bundleName = FilenameUtils.getBaseName(newBundleFile.getName());
if (!isModifyBundle(newBundleFile.getName()) || !onlyIncludeModifyBundle) {
return null;
}
if (null != logger) {
logger.info("[DiffApatch]" + bundleName);
}
final File newBundleUnzipFolder = new File(newBundleFile.getParentFile(), bundleName);
final File baseBundleUnzipFolder = new File(baseBundleFile.getParentFile(), bundleName);
if (null != baseBundleFile && baseBundleFile.isFile() && baseBundleFile.exists()) {
// 解压文件
ZipUtils.unzip(newBundleFile, newBundleUnzipFolder.getAbsolutePath());
ZipUtils.unzip(baseBundleFile, baseBundleUnzipFolder.getAbsolutePath());
// String patchBundleName = getBundleName(newBundleFile.getName());
String patchBundleName = FilenameUtils.getBaseName(newBundleFile.getName().replace("lib", ""));
if (null != patchBundleName) {
patchBundleName = patchBundleName.replace(".", "_");
List<File> bundlePatchs = createBundleAPatch(newBundleUnzipFolder, baseBundleUnzipFolder, patchTmpDir, patchBundleName, diffFile, diffJsonFile);
return bundlePatchs;
} else {
throw new PatchException("Cannot found bundle:" + newBundleFile.getName() + " in modifyBundleInfos.");
}
}
return null;
}
use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.
the class MergePatch method doMerge.
public File doMerge() throws PatchException {
try {
File dexFile = new File(out, "merge.dex");
if (dexFile.exists() && !dexFile.delete()) {
throw new RuntimeException("merge.dex can't be removed.");
}
File outFile = new File(out, "merge" + SUFFIX);
if (dexFile.exists() && !dexFile.delete()) {
throw new RuntimeException("merge" + SUFFIX + " can't be removed.");
}
if (patchs.length > 1) {
mergeCode(dexFile);
build(outFile, dexFile);
return release(out, dexFile, outFile);
} else if (patchs.length == 1) {
return patchs[0];
}
} catch (Exception e) {
throw new PatchException(e);
}
return null;
}
use of com.taobao.android.differ.dex.PatchException in project atlas by alibaba.
the class SmaliDiffUtils method scanClasses.
public static Set<DexBackedClassDef> scanClasses(File smaliDir, List<File> newFiles) throws PatchException {
Set<DexBackedClassDef> classes = Sets.newHashSet();
try {
for (File newFile : newFiles) {
DexBackedDexFile newDexFile = DexFileFactory.loadDexFile(newFile, 19, true);
Set<? extends DexBackedClassDef> dexClasses = newDexFile.getClasses();
classes.addAll(dexClasses);
}
final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
for (DexBackedClassDef classDef : classes) {
String className = classDef.getType();
ApkPatch.currentClassType = null;
AfBakSmali.disassembleClass(classDef, outFileNameHandler, getBuildOption(classes, 19), true, true);
File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
}
} catch (Exception e) {
throw new PatchException(e);
}
return classes;
}
Aggregations