Giter Club home page Giter Club logo

apkdiffpatch's People

Contributors

housisong avatar sisong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apkdiffpatch's Issues

ApkNormalized 损坏zip文件

我们都是**人,那我就不写英语了……xD
我发现 ApkNormalized 有两点问题:

  1. 重压缩的结果不一致(报错)
  2. 生成的zip文件 不符合zip文件标准

我以release中已编译好的hdiffpatch_v3.0.8_ApkDiffPatch_v1.3.1_bin_beta.zip为例

第一个问题出现在 Win64 版本ApkNormalized中,处理到最后会报错

UnZipper_fileData_decompressTo(srcZip,srcIndex,&stream) ERROR!
ApkNormalized result file check ERROR!

Win32版本和Linux64版本的执行结果相同,也不报错,其他版本没测试
我还没找出出问题的地方,不过我觉得这个问题不太大…应该是不同平台的数据类型长度变化导致的,改用定长类型int8_t,uint32_t等等应该就可以解决了

第二个问题 的现象就是ZIP文件损坏
用十六进制编辑器查看normalized的zip文件,会发现在PK头部之前多出来了4-6个空字节
把那几个00字节删掉之后,zip文件也不正确,但是具体哪里不正确我也没找出来(我不熟悉zip结构)
反正我用7-zip打开压缩包后无法修改或删除文件(7-zip提示“只读”,那意味着文件结构损坏,只能够读取,不能修改)

不需要ApkV2签名,但也要求patch结果二进制始终一致;也可以这样用(Released newZip :=ApkNormalized(newZip) before ZipDiff)

Released newZip :=ApkNormalized(newZip) before ZipDiff这样得出来的newZip试了好多遍还是MD5不一致,是什么原因呢?
win64命令步骤:
1、ApkNormalized.exe new.apk outnew.apk;
2、ZipDiff.exe old.apk outnew.apk patch.diff;
3、ZipPatch.exe old.apk patch.diff outToNew.apk;
但是这样得出来的apk和new.apk或者outnew.apk这三个的MD5都不一致

ApkPatch返回码

您好,请问客户端进行patch过程的返回码是否如下含义呢?

PATCH_SUCCESS=0, //0. 成功
PATCH_OPENREAD_ERROR, //1. 输入流打开失败
PATCH_OPENWRITE_ERROR, //2. 输出流打开失败
PATCH_CLOSEFILE_ERROR, //3. 关闭文件失败
PATCH_MEM_ERROR, //4. 运存空见不足(malloc失败)
PATCH_HPATCH_ERROR, //5. hpatch执行过程出错
PATCH_HDIFFINFO_ERROR, //6. diff文件信息错误(文件损坏?
PATCH_COMPRESSTYPE_ERROR, //7. 解压缩出错
PATCH_ZIPPATCH_ERROR, //8. (不确定)zip输出流写入异常
PATCH_ZIPDIFFINFO_ERROR, //9. zip格式下的diff文件读入失败(不可读)
PATCH_OLDDATA_ERROR, //10. 旧文件(旧apk)异常,跟diff文件里对不上
PATCH_OLDDECOMPRESS_ERROR, //11. 旧文件(旧apk)解压异常
PATCH_OLDSTREAM_ERROR, //12. 旧文件(旧apk)输入流异常
PATCH_NEWSTREAM_ERROR, //13. 新文件(新apk)输出流异常

谢谢~~~

提供v2签名Apk的多渠道包技术层支持

当前每个渠道必须要单独生成其补丁包;
库提供一个工具,允许生成某种基础补丁包,并提供另外一个工具允许快速修改该补丁包来生成适合不同渠道的补丁包;

Android中使用ZipPatch问题

在安卓使用so文件,对于patch方法:
public static native int patch(String oldApkPath,String patchFilePath,String outNewApkPath,
long maxUncompressMemory,String tempUncompressFilePath,int threadNum);

1、请问 maxUncompressMemory、tempUncompressFilePath这两个参数是用于解压的时候使用的临时最大存储空间和该存储空间的路径吗?对于这个的空间分配和进行oldZip,diffZip,newZip文件的大小有最优的映射吗?这个问题和上面的那个线程数量的问题类似。

2、我在使用的合成1G的文件的时候分配了1024 *10空间,但是在合成的整个过程中(运行中和运行后)并没有看到我指定的路径下面有该临时文件的生成,这是什么原因呢?

给 无法自己重签名的V2SignApk包 提供一个强制diff工具

理论上,只要当前zlib库(或者收集的其他常见兼容库)能够匹配上部分newApk的压缩编码输出(反算出压缩参数),就能降低部分补丁大小;
old apk 分为是否V2签名的情况分别处理(无v2签名的不能够过于信任其不会简单变动);
new apk对每个文件区分匹配压缩参数;

补丁大小最差情况接近HDiffPatch或BsDiff的结果,最好结果接近ApkDiffPatch中ZipDiff的结果;
patch速度因为压缩参数的原因,可能会比较慢;

用libdeflate替换zlib加快zip包生成速度

  1. 和zlib生成的编码不同,升级用的工具链需要处理兼容和长期过渡问题;
  2. 也因为和zlib生成的编码不同,可能在谷歌play商店遇到部分升级补丁大小优化兼容问题;
  3. libdeflate不支持流式压缩,使用环境部分受限;

优化oldRefList

当前默认引用了oldZip中的所有文件,不利于patch阶段的执行性能;
优化:从中去除对newZip没有太多参考价值的文件;减少patch时的解压文件数;

Native异常:signal 11 (SIGSEGV) , code 1 (SEGV_MAPERR), fault addr 0xdeadcab1:

线上环境有一定概率出来这个问题,看起来是空指针,野指针的问题,具体的堆栈为:

0	#00 pc 000000000001ac5c /xxx/libapkpatch.so
1	#01 pc 000000000001ac7c /xxx/libapkpatch.so
2	#02 pc 000000000001ac48 /xxx/libapkpatch.so
3	#03 pc 000000000001a268 /xxx/libapkpatch.so
4	#04 pc 000000000001a0ec /xxx/libapkpatch.so
5	#05 pc 000000000001a09c /xxx/libapkpatch.so
6	#06 pc 0000000000012ec8 /xxx/libapkpatch.so
7	#07 pc 000000000001451c /xxx/libapkpatch.so
8	#08 pc 00000000000144a0 /xxx/libapkpatch.so
9	#09 pc 0000000000018404 /xxx/libapkpatch.so
10	#10 pc 0000000000015fa8 /xxx/libapkpatch.so
11	#11 pc 0000000000016424 /xxx/libapkpatch.so
12	#12 pc 00000000000074ac /xxx/libapkpatch.so (Java_com_github_sisong_ApkPatch_patch+208)

@sisong 请问遇到过这个问题吗?或者能查到原因吗?

生成新包失败问题

大佬你好,
我在libs里添加了armea-v7a/libapkpatch.so.加载so文件也成功。
在Activity oncreate()调用
ApkPatch.patch(oldApkPath, oldDiffpath, newApkpath,maxUncompressMemory,tempUncompressFilePath,1)
参数:
String root = Environment.getExternalStorageDirectory().getAbsolutePath();
String oldApkPath = root+"/1/old.apk";
String oldDiffpath = root+"/1/add.diff";
String newApkpath = root+"/1/new.apk";
long maxUncompressMemory = 810241024;//8mb
String tempUncompressFilePath=root+"/360/";
没有生成新包,返回值1。

ZipPatch问题

我在Android上使用patch合成一个new.apk,但是这个new.apk却在android中读取不出来所有的ZipEntry:
使用如下程序读取不出来:
ZipFile zipFile = new ZipFile(filePath);
InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(filePath));
ZipEntry zipEntry;
HashMap<String, InputStream> inputStreamHashMap = new HashMap<>();
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (zipEntry.isDirectory()) {
continue;
} else {
String name = zipEntry.getName();
Log.d(TAG, "-------" + name);
}

请问是什么原因呢?

关于Apk差分和合成过程中设置忽略文件的问题

您好,请问:

    - 如果我在对APK进行差分和合成的过程中是否能够指定对某些文件进行忽略呢?
    - 如果没有这个参数的话我是否能够在源码中能够有对应的处理的逻辑进行修改源码呢?例如我需要忽略APK文件中的Zip Comment的内容,或者忽略META-INF文件夹中指定的文件。有办法可以做到吗?

感谢~

没理解这句说明

if your apk used Apk v2 sign(or Apk v3 sign), Released newZip := AndroidSDK#apksigner(ApkNormalized(newZip)) before ZipDiff;

AndroidSDK#apksigner 是指的哪个方法吗?

ApkNormalized对Apk正则化之后使用7zip解压出现问题

出现原因:当apk中的assets中存在一个空文件(可以自己随便创建一个文本为空的文件),这时候使用ApkNormalized进行正则化之后,再使用7 zip工具进行解压,会出现错误,错误日志为:数据错误assets/nullfile

请问出现该错误的原因是什么呢?您那边方便分析一下吗?

备注:自己随便造一个apk都会出现该错误

空间复杂度问题:ZipPatch() requires 4*(decompress stream memory) + ref old decompress memory + O(1), also ref old decompress can use temp disk file without memory;

根据readme中看到空间复杂度为 4*解压流内存 + 引用旧文件解压内存 + O(1):
请问一般解压流大概是多少的呢?比如对1G的文件进行操作大概会占用多少内存呢?
我在Android上使用的时候进行合成一个1G的文件竟然没有发现占用的内存没有明显的变化,感到很奇怪

获取的包已经是子渠道包了,所以这个Patch理论上应该是不成功的,不知道这个问题如何解决,还请解惑

simonking200:
您好,首先非常感谢您能够分享HDiffPatch这个非常棒的库,我现在使用的是HDiffPatch,目前我也遇到的这样的实际问题,一般渠道会从新组包生成很多子渠道。组包过程原包又是从安装目录中获取的,这时候获取的包已经是子渠道包了,所以这个Patch理论上应该是不成功的,不知道这个问题如何解决,还请解惑

Originally posted by @simonking200 in #12 (comment)

ApkPatch.patch return 5

hi,同一份old.apk,new.apk数据,我在PC上ZipDiff ZipPatch 操作测试一切正常,可在android设备安装old.apk,获取diff数据后进行合并每次都返回5,麻烦能帮忙分析下这个code产生的原因吗(已测试将android设备下载的diff文件拷贝到PC进行ZipPatch,结果正常)
ApkPatch.patch(String oldApkPath, String patchFilePath, String outNewApkPath, long maxUncompressMemory, String tempUncompressFilePath, int threadNum)
参数如下:
oldApkPath: /data/app/package-PkGyHOmlXf2mGU8Ln6LzrQ==/base.apk
patchFilePath: /storage/emulated/0/Android/data/package/cache/patch.diff
outNewApkPath: /storage/emulated/0/Android/data/package/cache/patch.apk
maxUncompressMemory: 1024*512
tempUncompressFilePath: /storage/emulated/0/Android/data/package/cache/patch.temp
threadNum: 3

ApkNormalized问题

您好,如您所说:if your need newZip(patch result) file byte by byte equal, Released newZip := ApkNormalized(newZip) before run ZipDiff, AND You should not modify the zlib version (unless it is certified compatible);
if your apk(or jar) file used Jar sign(Apk v1 sign), is same as zip file;
if your apk used Apk v2 sign(or Apk v3 sign), Released newZip := AndroidSDK#apksigner(ApkNormalized(newZip)) before ZipDiff;

关于ApkNormalized的问题

您好,如您所说:if your need newZip(patch result) file byte by byte equal, Released newZip := ApkNormalized(newZip) before run ZipDiff, AND You should not modify the zlib version (unless it is certified compatible);
if your apk(or jar) file used Jar sign(Apk v1 sign), is same as zip file;
if your apk used Apk v2 sign(or Apk v3 sign), Released newZip := AndroidSDK#apksigner(ApkNormalized(newZip)) before ZipDiff;

问题:
1、我这边需要在v2签名的情况下,在apk中进行了patch之后在进行ApkNormalized吗?
2、在v1签名的情况下,是需要对old.apk,new.apk都进行了ApkNormalized之后,在apk合成的之后中需要进行ApkNormalized吗?
3、如果上述问题是需要在apk合成的之后进行ApkNormalized的话,那这个过程是在android手机中进行的,那有这部分的库吗?

thx~~~

ZipDiff过程中对ApkNormalized文件进行差分检测错误

输出部分日志如下:

oldZip :"2_3_nor.apk"
newZip :"1_2_nor.apk"
outDiff :"patch.diff"
NOTE: oldZip found JarSign(ApkV1Sign)
NOTE: newZip maybe normalized
NOTE: newZip found JarSign(ApkV1Sign)

其中2_3_nor.apk和1_2_nor.apk都是进过normalized之后的文件,但是只有一个newZip maybe normalized,我看源码中有如下源码:

static bool checkZipInfo(UnZipper* oldZip,UnZipper* newZip){
bool isOk=true;
if (oldZip->_isDataNormalized)
printf(" NOTE: oldZip maybe normalized\n");
if (UnZipper_isHaveApkV1_or_jarSign(oldZip))
printf(" NOTE: oldZip found JarSign(ApkV1Sign)\n");
if (UnZipper_isHaveApkV2Sign(oldZip))
printf(" NOTE: oldZip found ApkV2Sign\n");
if (UnZipper_isHaveApkV3Sign(oldZip))
printf(" NOTE: oldZip found ApkV3Sign\n");
if (newZip->_isDataNormalized)
printf(" NOTE: newZip maybe normalized\n");
if (UnZipper_isHaveApkV1_or_jarSign(newZip))
printf(" NOTE: newZip found JarSign(ApkV1Sign)\n");
bool newIsV2Sign=UnZipper_isHaveApkV2Sign(newZip);
if (newIsV2Sign)
printf(" NOTE: newZip found ApkV2Sign\n");
if (UnZipper_isHaveApkV3Sign(newZip))
printf(" NOTE: newZip found ApkV3Sign\n");

if (newIsV2Sign&(!newZip->_isDataNormalized)){
    //maybe bring apk can't install ERROR!
    printf("  ERROR: newZip not Normalized, need do "
           "newZip=AndroidSDK#apksigner(ApkNormalized(newZip)) before running ZipDiff!\n");
    isOk=false;
}
if ((!newIsV2Sign)&&UnZipper_isHaveApkV2orV3SignTag_in_ApkV1SignFile(newZip)){
    //maybe bring apk can't install ERROR!
    printf("  ERROR: newZip fond \"X-Android-APK-Signed: 2(or 3...)\" in ApkV1Sign file, need re sign "
           "newZip:=AndroidSDK#apksigner(newZip) before running ZipDiff!\n");
    isOk=false;
}
printf("\n");
return isOk;

}

按照源码应该是有NOTE: oldZip maybe normalized输出的才是,这是什么原因呢?

ZipDiff问题

在进行ZipDiff的时候命令行显示部分如下:

ZipDiff with compress plugin: "lzma"
ZipDiff same file count: 1184 (all 1977)
diff new file count: 793
ref old file count: 1778 (all 1833)
ref old decompress: 19 file (16931246 byte!)

run hdiffz:
oldDataSize : 25320411
newDataSize : 70138231
(used one lzma dictSize: 393216 (input data: 300626))
(used one lzma dictSize: 3145728 (input data: 2414172))
(used one lzma dictSize: 3145728 (input data: 2934300))
(used one lzma dictSize: 4194304 (input data: 49753616))
diffDataSize: 25113120
diff time: 34.109 s
hpatchz check hdiffz result ok!
patch time: 1.297 s

(used one lzma dictSize: 6144 (input data: 4236))
ZipDiff size: 25113495
ZipDiff time: 40.047 s

run ZipPatch:
check ZipPatch result Same Like ok! (but not Byte By Byte Equal)
patch time: 5.078 s

all time: 45.125 s

问题一:

请问其中4个dictSize:
(used one lzma dictSize: 393216 (input data: 300626))
(used one lzma dictSize: 3145728 (input data: 2414172))
(used one lzma dictSize: 3145728 (input data: 2934300))
(used one lzma dictSize: 4194304 (input data: 49753616))
这4个的大小是怎么确定的?和什么有关?我这边是否可以自行定义大小?


问题二:

请问在出现了4个dictSize并显示diff完成之后还出现了:
(used one lzma dictSize: 6144 (input data: 4236))
这个的作用是什么呢?是否会计入patch时候的空间复杂度计算中?大小是由什么决定的呢?

编译后的可执行文件

你好:
我下了hdiffpatch_v3.0.8_ApkDiffPatch_v1.3.2_bin_beta 这个包,
运行 ZipDiff 和 ZipPatch 之后,V2签名的apk 不能正常安装。但是
我试了
hdiffz.exe
hpatchz.exe
可以!
所以想问下, 这两个文件是怎么通过源码编译生成的?

support zip64? #Rejected

ApkDiffPatch 针对的场景中,都是不太大的zip包文件;
支持的必要性不强;

请问下,重新签名后patch反而变大了。没有重新签名直接生成的patch是400多k,重新签名后生成的反而是1.2M。比google的archive-patcher 的patch包大,与您这边的测试结果好像不符合。使用的是v2签名的Apk

请问下,重新签名后patch反而变大了。没有重新签名直接生成的patch是400多k,重新签名后生成的反而是1.2M。比google的archive-patcher 的patch包大,与您这边的测试结果好像不符合。使用的是v2签名的Apk

Originally posted by @super-h-c in #73 (comment)

Problem with split apks (INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2)

Hello,

I'm trying to use ZipDiff for the Twitter app.

When downloading for an arm64 device from the German Google Play Store, this comes in 5 .apk files:

  • base.apk
  • split_config.arm64_v8a.apk
  • split_config.de.apk
  • split_config.en.apk
  • split_config.xxhdpi.apk

Unfortunately, if I apply AndroidSDK#apksigner(ApkNormalized(AndroidSDK#apksigner(newZip))) to split_config.arm64_v8a.apk I get the following error when installing with adb install-multiple *.apk:

adb: failed to finalize session
Failure [INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2]

Installing works without problems if I only apply AndroidSDK#apksigner(newZip) to split_config.arm64_v8a.apk and AndroidSDK#apksigner(ApkNormalized(AndroidSDK#apksigner(newZip))) tothe other .apk files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.