一、UpgradePatch类
tryPatch(Context context, String tempPatchPath, PatchResult patchResult)
方法
PatchFile:
/storage/emulated/0/patch_signed_7zip.apk
PatchDirectory: /data/data/tinker.sample.android/tinker
PatchVersionDirectory: /data/data/tinker.sample.android/tinker/patch-931e8e6c
DesPatchFile: /data/data/tinker.sample.android/tinker/patch- 931e8e6c/patch-931e8e6c.apk
PatchMd5: 931e8e6c07fc199bf33ef872510900a5
PatchInfoFile: /data/data/tinker.sample.android/tinker/patch.info
newInfo = new SharePatchInfo("", patchMd5);
getPatchInfoLockFile: /data/data/tinker.sample.android/tinker/info.lock
二、DexDiffPatchInternal类
第一种对应完全新增的dex,第二种对应本来没变化,但是由于其他dex的变化需要打入这个dex里引用了那个变化了的dex的类
patchRealPath: classes.dex
final String infoPath = info.path;
String patchRealPath;
if(infoPath.equals("")) {
patchRealPath = info.rawName;}
else {
patchRealPath = info.path + "/" + info.rawName;
}
directory: /data/data/tinker.sample.android/tinker/patch-931e8e6c/dex
dir: /data/data/tinker.sample.android/tinker/patch-931e8e6c/dex/
ApkPath或者Application.sourcedir: /data/app/tinker.sample.android-2/base.apk
extractedFile:/data/data/tinker.sample.android/tinker/patch- 931e8e6c/dex/smallpatch_info.ddextra
File extractedFile = new File(dir + info.realName);
/data/data/tinker.sample.android/tinker/patch-931e8e6c/dex/classes.dex.jar
ZipEntry patchFileEntry = patch.getEntry(patchRealPath); ZipEntry rawApkFileEntry = apk.getEntry(patchRealPath);
oldDexSize = (int) rawApkFileEntry.getSize();
原始apk中class.dex
的大小
InputStream oldInputStream = apk.getInputStream(rawApkFileEntry); InputStream newInputStream = patch.getInputStream(patchFileEntry);
SmallPatchedDexItemFile : /data/data/tinker.sample.android/tinker/patch-931e8e6c/dex/smallpatch_info.ddextra
- 构造方法,
zos
是extractedFile
new DexPatchApplier(oldInputStream, oldDexSize, newInputStream,
smallPatchInfoFile).executeAndSaveTo(zos);
public DexPatchApplier(
InputStream oldDexIn,
int initDexSize,
InputStream patchFileIn,
SmallPatchedDexItemFile extraInfoFile) throws IOException {
this(
new Dex(oldDexIn, initDexSize),
(patchFileIn != null ? new DexPatchFile(patchFileIn) : null),
extraInfoFile
);
}
this.extraInfoFile = SmallPatchedDexItemFile;
if (extraInfoFile == null || !extraInfoFile.isAffectedOldDex(this.oldDexSignStr)) {
patchedToc.stringIds.off
= this.patchFile.getPatchedStringIdSectionOffset();
} else {
patchedToc.stringIds.off =
this.extraInfoFile.getPatchedStringIdOffsetByOldDexSign(oldDexSignStr);
小dex
如果为空,则使用patchFile
来计算位置偏移。
-
TableOfContents patchedToc = this.patchedDex.getTableOfContents();
根据patchedDex来得到,而patchedDex又等于:。
if (extraAddedDexElementsFile == null) {
this.patchedDex = new Dex(patchFileIn.getPatchedDexSize());
} else {
this.patchedDex = new Dex(
extraAddedDexElementsFile.getPatchedDexSizeByOldDexSign(this.oldDexSignStr)
);
}
- 接着,根据区域分块,执行算法合成。
- 最后得到的是extractedFile,对比extractedFileMd5.
String extractedFileMd5 = ShareTinkerInternals.isVmArt() ? info.destMd5InArt : info.destMd5InDvm;
得到extracted文件之后
File dexFiles = new File(dir); File[] files = dexFiles.listFiles();
files = {File[2]@4819}
0 = {File@4822} "/data/data/tinker.sample.android/tinker/patch-931e8e6c/dex/classes.dex.jar"
1 = {File@4823} "/data/data/tinker.sample.android/tinker/patch-931e8e6c/dex/test.dex.jar"
optimizeDexDirectory: /data/data/tinker.sample.android/tinker/patch- 931e8e6c/odex/
outputPathName : /data/data/tinker.sample.android/tinker/patch- 931e8e6c/odex/classes.dex.dex
file: /data/data/tinker.sample.android/tinker/patch- 931e8e6c/dex/classes.dex.jar
最后调用
DexFile.loadDex(file.getAbsolutePath(), outputPathName, 0);
三、ShareDexDiffPatchInfo
class.dex
destMd5InArt = "0b7ac225cab45910bff62ca2851a10ba"
destMd5InDvm = "68c3b5f96dfe971c0d44398ddffd6a35"
dexDiffMd5 = "84aab131677430f22b35fc4668f44423"
dexMode = "jar"
isJarMode = true
oldDexCrC = "2996628334"
path = ""
rawName = "classes.dex"
realName = "classes.dex.jar"
shadow$_klass_ = {Class@4358} "class com.tencent.tinker.loader.shareutil.ShareDexDiffPatchInfo"
shadow$_monitor_ = -1618719825
还会有一个test.dex
:
destMd5InArt = "56900442eb5b7e1de45449d0685e6e00"
destMd5InDvm = "56900442eb5b7e1de45449d0685e6e00"
dexDiffMd5 = "0"
dexMode = "jar"
isJarMode = true
oldDexCrC = "0"
path = ""
rawName = "test.dex"
realName = "test.dex.jar"
shadow$_klass_ = {Class@4358} "class com.tencent.tinker.loader.shareutil.ShareDexDiffPatchInfo"
shadow$_monitor_ = -1618719825
当oldDexCrC=0
时,完全新增的dex。调用extractDexToJar方法
extractTo: /data/data/tinker.sample.android/tinker/patch- 931e8e6c/dex/test.dex.jar
entryFile: test.dex
patch中的它写入extractTo里面。
test.dex
是测试插入是否第一次的,有些手机可以插入dex,但不会生效。