ios怎么允许增量下载怎么弄?

增量导出入_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
增量导出入
上传于||暂无简介
你可能喜欢一种POS终端程序增量下载的方法
申请号:.3 申请日:
摘要:一种POS终端程序增量下载的方法,其包括以下步骤:S1:查询POS终端上的现有文件,并比较现有文件和将要下载至POS终端的待下载文件;S2:若待下载文件与现有文件相比不是全新文件,分段对比所述的待下载文件与现有文件;S3:根据分段的待下载文件与分段的现有文件的差异,生成段差异信息;S4:发送所述段差异信息至POS终端;S5:POS终端利用所述的现有文件和段差异信息重构出待更新文件;S6:POS终端校验所述待更新文件并进行升级。本发明减少了文件传输的大小,节省了时间和流量,同时大大提升了用户体验,可广泛应用于数据下载领域。
地址: 518040 广东省深圳市福田区沙头街道泰然劲松大厦17B
发明(设计)人:
主分类号:
&实质审查的生效IPC(主分类):G06F
9/445申请日:
注:本法律状态信息仅供参考,即时准确的法律状态信息须到国家知识产权局办理专利登记簿副本。
&一种POS终端程序增量下载的方法,其特征在于:其包括以下步骤:S1:查询POS终端上的现有文件,并比较现有文件和将要下载至POS终端的待下载文件;S2:若待下载文件与现有文件相比不是全新文件,分段对比所述的待下载文件与现有文件;S3:根据分段的待下载文件与分段的现有文件的差异,生成段差异信息;S4:发送所述段差异信息至POS终端;S5:POS终端利用所述的现有文件和段差异信息重构出待更新文件;S6:POS终端校验所述待更新文件并进行升级。
专利代理机构
进入国家日期Android 增量更新流程讲解 - 推酷
Android 增量更新流程讲解
为什么需要增量更新:节省流量,节省流量,节省流量,重要的事情说三遍!
增量更新不仅可以让用户在客户端实现省流量更新,更重要的是增量更新还可以实现服务器端流量的节省,为网站节省成本。
增量更新的原理
服务端将应用的旧版本Apk与新版本Apk做差分处理,得到新版APK更新部分的差分包,例如旧版本的APK有6M,新版的有10M,更新的部分则可能只有4M左右(这4M文件除了包含更新内容以外,还包含一些上下文相关的东西),对于服务端来讲,如果是大型应用每次用户下载数量在百万以上,那么数百万*4M节省到的流量可想而知。这里强调一点,新apk和旧apk生成的差分包,其体积大小一定要小于新apk的体积,否则增量更新无意义。
客户端在用户下载了差分更新包之后,将手机端存在的旧版本软件APK(大多处在/data/data/app/下),复制到SD卡或者cache中,并与差分更新包进行合并,得到一个新版本的apk升级安装包,最终,这个生成的apk和你做差分之前的apk是一致的。
为了得到增量更新中的差分包,我们使用网上一款非常有名的开源二进制查分工具bsdiff。其中bsdiff依赖bzip2,所以我们还需要用到 bzip2工具。
关于bsdiff大家可以去官网下载
关于bzip2大家可以去官网下载
下载后的bsdiff目录如下
在bsdiff中,bsdiff.c 用于生成差分包,bspatch.c 用于合并文件。
ok,准备就绪下面开始步入正题,我将分为服务端和客户端两个方面给大家讲解。讲之前,还是先画个图,给大家从全局上描绘一下。
客户端开发流程讲解
第1步.下载服务端的差分包
下面是通过自定义的下载方法,得到差分包文件patchFile 。
String downUrl = &/apk.patch&;
File patchFile = DownloadUtils.download(downUrl);
public static File download(String url){
File file = null;
InputStream is = null;
FileOutputStream os = null;
file = new File(Environment.getExternalStorageDirectory(),Constants.PATCH_FILE);
if (file.exists()) {
file.delete();
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
is = conn.getInputStream();
os = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
} catch(Exception e){
e.printStackTrace();
os.close();
} catch (IOException e) {
e.printStackTrace();
is.close();
} catch (IOException e) {
e.printStackTrace();
第2步.合并得到最新版本的APK文件
String oldfile = ApkUtils.getSourceApkPath(MainActivity.this, getPackageName());
String newfile = Constants.NEW_APK_PATH;
String patchfile = patchFile.getAbsolutePath();
BsPatch.patch(oldfile, newfile, patchfile);
这里的BsPatch是我们的定义的调用Native方法的类
public class BsPatch {
* @param oldfile 旧版本文件
* @param newfile 新版本文件
* @param patchfile 合并后的文件
public native static void patch(String oldfile, String newfile, String patchfile);
System.loadLibrary(&bspatch&);
其中加载的baspatch.c文件
__FBSDID(&$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1
01:59:06 cperciva Exp $&);
#include &bzlib.h&
#include &stdlib.h&
#include &stdio.h&
#include &string.h&
#include &err.h&
#include &unistd.h&
#include &fcntl.h&
static off_t offtin(u_char *buf)
y=buf[7]&0x7F;
y=y*256;y+=buf[6];
y=y*256;y+=buf[5];
y=y*256;y+=buf[4];
y=y*256;y+=buf[3];
y=y*256;y+=buf[2];
y=y*256;y+=buf[1];
y=y*256;y+=buf[0];
if(buf[7]&0x80) y=-y;
int main(int argc,char * argv[])
FILE * f, * cpf, * dpf, *
BZFILE * cpfbz2, * dpfbz2, * epfbz2;
int cbz2err, dbz2err, ebz2
ssize_t oldsize,
ssize_t bzctrllen,
u_char header[32],buf[8];
u_char *old, *new;
off_t oldpos,
off_t ctrl[3];
if(argc!=4) errx(1,&usage: %s oldfile newfile patchfile\n&,argv[0]);
/* Open patch file */
if ((f = fopen(argv[3], &r&)) == NULL)
err(1, &fopen(%s)&, argv[3]);
File format:
&BSDIFF40&
sizeof(newfile)
bzip2(control block)
bzip2(diff block)
??? bzip2(extra block)
with control block a set of triples (x,y,z) meaning &add x bytes
from oldfile to x bytes copy y bytes from the
seek forwards in oldfile by z bytes&.
/* Read header */
if (fread(header, 1, 32, f) & 32) {
if (feof(f))
errx(1, &Corrupt patch\n&);
err(1, &fread(%s)&, argv[3]);
/* Check for appropriate magic */
if (memcmp(header, &BSDIFF40&, 8) != 0)
errx(1, &Corrupt patch\n&);
/* Read lengths from header */
bzctrllen=offtin(header+8);
bzdatalen=offtin(header+16);
newsize=offtin(header+24);
if((bzctrllen&0) || (bzdatalen&0) || (newsize&0))
errx(1,&Corrupt patch\n&);
/* Close patch file and re-open it via libbzip2 at the right places */
if (fclose(f))
err(1, &fclose(%s)&, argv[3]);
if ((cpf = fopen(argv[3], &r&)) == NULL)
err(1, &fopen(%s)&, argv[3]);
if (fseeko(cpf, 32, SEEK_SET))
err(1, &fseeko(%s, %lld)&, argv[3],
(long long)32);
if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)
errx(1, &BZ2_bzReadOpen, bz2err = %d&, cbz2err);
if ((dpf = fopen(argv[3], &r&)) == NULL)
err(1, &fopen(%s)&, argv[3]);
if (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
err(1, &fseeko(%s, %lld)&, argv[3],
(long long)(32 + bzctrllen));
if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)
errx(1, &BZ2_bzReadOpen, bz2err = %d&, dbz2err);
if ((epf = fopen(argv[3], &r&)) == NULL)
err(1, &fopen(%s)&, argv[3]);
if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
err(1, &fseeko(%s, %lld)&, argv[3],
(long long)(32 + bzctrllen + bzdatalen));
if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL)
errx(1, &BZ2_bzReadOpen, bz2err = %d&, ebz2err);
if(((fd=open(argv[1],O_RDONLY,0))&0) ||
((oldsize=lseek(fd,0,SEEK_END))==-1) ||
((old=malloc(oldsize+1))==NULL) ||
(lseek(fd,0,SEEK_SET)!=0) ||
(read(fd,old,oldsize)!=oldsize) ||
(close(fd)==-1)) err(1,&%s&,argv[1]);
if((new=malloc(newsize+1))==NULL) err(1,NULL);
oldpos=0;newpos=0;
while(newpos&newsize) {
/* Read control data */
for(i=0;i&=2;i++) {
lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
if ((lenread & 8) || ((cbz2err != BZ_OK) &&
(cbz2err != BZ_STREAM_END)))
errx(1, &Corrupt patch\n&);
ctrl[i]=offtin(buf);
/* Sanity-check */
if(newpos+ctrl[0]&newsize)
errx(1,&Corrupt patch\n&);
/* Read diff string */
lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]);
if ((lenread & ctrl[0]) ||
((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
errx(1, &Corrupt patch\n&);
/* Add old data to diff string */
for(i=0;i&ctrl[0];i++)
if((oldpos+i&=0) && (oldpos+i&oldsize))
new[newpos+i]+=old[oldpos+i];
/* Adjust pointers */
newpos+=ctrl[0];
oldpos+=ctrl[0];
/* Sanity-check */
if(newpos+ctrl[1]&newsize)
errx(1,&Corrupt patch\n&);
/* Read extra string */
lenread = BZ2_bzRead(&ebz2err, epfbz2, new + newpos, ctrl[1]);
if ((lenread & ctrl[1]) ||
((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
errx(1, &Corrupt patch\n&);
/* Adjust pointers */
newpos+=ctrl[1];
oldpos+=ctrl[2];
/* Clean up the bzip2 reads */
BZ2_bzReadClose(&cbz2err, cpfbz2);
BZ2_bzReadClose(&dbz2err, dpfbz2);
BZ2_bzReadClose(&ebz2err, epfbz2);
if (fclose(cpf) || fclose(dpf) || fclose(epf))
err(1, &fclose(%s)&, argv[3]);
/* Write the new file */
if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))&0) ||
(write(fd,new,newsize)!=newsize) || (close(fd)==-1))
err(1,&%s&,argv[2]);
free(new);
free(old);
为了JNI开发方便,我们可以生成BsPatch的头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include &jni.h&
/* Header for class com_castiel_inupdate_utils_BsPatch */
#ifndef _Included_com_castiel_inupdate_utils_BsPatch
#define _Included_com_castiel_inupdate_utils_BsPatch
#ifdef __cplusplus
extern &C& {
com_castiel_inupdate_utils_BsPatch
* Signature: (Ljava/lang/SLjava/lang/SLjava/lang/S)V
JNIEXPORT void JNICALL Java_com_castiel_inupdate_utils_BsPatch_patch
(JNIEnv *, jclass, jstring, jstring, jstring);
#ifdef __cplusplus
Android.mk文件配置
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= bspatch
LOCAL_SRC_FILES:= bspatch.c
include $(BUILD_SHARED_LIBRARY)
第3步.安装合并后的新APK
String newApkPath = Environment.getExternalStorageDirectory() + File.separator + &castielNew.apk&;
installApk(MainActivity.this, newApkPath);
* @param context
* @param apkPath
public static void installApk(Context context, String apkPath) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(&file://& + apkPath),
&application/vnd.android.package-archive&);
context.startActivity(intent);
注意不要忘记添加权限
&uses-permission android:name=&android.permission.INTERNET&/&
&uses-permission android:name=&android.permission.WRITE_EXTERNAL_STORAGE&/&
&uses-permission android:name=&android.permission.MOUNT_UNMOUNT_FILESYSTEMS&/&
服务端开发流程讲解
其实开发非常简单,这里我简单的说明一下关键源码
public class BsDiff {
* 导入差分库,调用差分方法
* @param oldfile
* @param newfile
* @param patchfile
public native static void diff(String oldfile, String newfile, String patchfile);
System.loadLibrary(&bsdiff.so&);
测试得到差分包
public class Test {
public static final String OLD_APK_PATH = &你服务器端的路径/castiel_old.apk&;
public static final String NEW_APK_PATH = &你服务器端的路径/castiel_new.apk&;
public static final String PATCH_PATH = &你服务器端的路径/castiel/apk/apk.patch&;
public static void main(String[] args) {
//得到差分包
BsDiff.diff(ConstantsWin.OLD_APK_PATH, ConstantsWin.NEW_APK_PATH, ConstantsWin.PATCH_PATH);
增量更新的问题
增量更新在实施中,我们无法保证用户每次都能够及时升级到最新版本,所以必须对所发布的每一个版本都和最新的版本作差分处理,以便让所有版本的用户都可以进行差分升级,这样的流程除非通过自动化的脚本批量生成否则比较繁琐。
增量更新对于手机内存无法提供足够空间用作本地APK合成的用户和本地APK损坏的用户来说,是无法实现的。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致如何使用FTP进行增量复制_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
如何使用FTP进行增量复制
上传于||文档简介
&&f​t​p​的​增​量​复​制​的​配​置​方​式
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 怎么支持增量下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信