博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
05.Eclipse下Ndk开发(增量更新)
阅读量:6945 次
发布时间:2019-06-27

本文共 21279 字,大约阅读时间需要 70 分钟。

(创建于2017/12/17)

1.服务器生成差分包

服务器生成通常是在web项目中进行的,和客户端开发类似,先生成动态库,然后调用,我们创建一个web项目如下目录结构

img_e5adc44b6347634e22268d8d879c9d3a.png
6825421.png

创建过程中涉及到一些问题

a.eclipse无法创建web项目,说明你的eclipse并没有下载一下需要的插件,百度可以找到答案

(1)在确定联网的情况下,在help->install new software下根据你的eclipse版本选择下拉框选项,例如eclipse indigo,所选情况如下:

img_38f3add8e7ad962ac7678bf76f2bef34.png
0.16042005052183117.png

或者我的是luna

img_8807e36ddd7a81031087d949cf18e29f.png
7147390.png
(2)在下面的下拉框中 Web, XML, Java EE and OSGi Enterprise Development选择如下几个插件;
img_f184d37f9d2356a39bbbaf9854b4ca49.png
0.6712919270664064.png

(3)安装这几个插件,耐心等待........安装完成之后,会自动弹出对话框让你重启eclipse,重启下就行,此时,就可以新建web项目了,如下:

img_387e0e18f0f78b1a378997f8c7723457.png
0.4208209828158662.png
(4)到了这里还没有完,你会发现创建项目的时候无法选择到tomcat服务器,这同样是缺少插件的原因同样在
Web, XML, Java EE and OSGi Enterprise Development
选择JST Server AdaptersExtensions,或者还有一个相似的也选上

这时就可以创建web工程了,这只是一个小插曲,其实我们可以直接写Java工程的,不过为了模拟的真实一些

2.接下来创建native方法,生成头文件,放入到visual studio中编写代码

public class DiffUtils {    static{        System.loadLibrary("ndk_update");    }    public native static void diff(String old,String newFile,String patchFile);}
/* DO NOT EDIT THIS FILE - it is machine generated */#include 
/* Header for class ndk_update_server_DiffUtils */#ifndef _Included_ndk_update_server_DiffUtils#define _Included_ndk_update_server_DiffUtils#ifdef __cplusplusextern "C" {#endif/* * Class: ndk_update_server_DiffUtils * Method: diff * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_ndk_1update_1server_DiffUtils_diff (JNIEnv *, jclass, jstring, jstring, jstring);#ifdef __cplusplus}#endif#endif

3.as工程目录概览

img_bb2fe0112d62d9e498a0b0c6d2c7214a.png
7768218.png

源文件中8个文件和头文件中的两个文件bzlib.h和bzilib_private.h都是bsdiff中拷贝过来的,有一点需要注意,as

时windows环境,所以我们下载的bsdiff需要时Windows版的
在bsdiff.cpp文件中写代码,如下

/*- * Copyright 2003-2005 Colin Percival * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted providing that the following conditions  * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE.*/#include 
#include "bzlib.h"#include
#include
//#include
//#include
#include
#include
//#include
#include "ndk_update_server_DiffUtils.h"#include
#include
#include
typedef unsigned char u_char;typedef long pid_t;template
void err(int i, const char* str, T arg) { char lastErrorTxt[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL); printf("%s",lastErrorTxt); printf(str, arg); exit(i);}void err(int i, const char* str) { char lastErrorTxt[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),0,lastErrorTxt,1024,NULL); printf("%s",lastErrorTxt); if (str!=NULL) { printf("%s",str); } exit(i);}template
void errx(int i, const char* str, T arg) { printf(str, arg); exit(i);}void errx(int i, const char* str) { printf("%s",str); exit(i);}#define MIN(x,y) (((x)<(y)) ? (x) : (y))static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h){ off_t i,j,k,x,tmp,jj,kk; if(len<16) { for(k=start;k
start) split(I,V,start,jj-start,h); for(i=0;i
kk) split(I,V,kk,start+len-kk,h);}static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize){ off_t buckets[256]; off_t i,h,len; for(i=0;i<256;i++) buckets[i]=0; for(i=0;i
0;i--) buckets[i]=buckets[i-1]; buckets[0]=0; for(i=0;i
y) { *pos=I[st]; return x; } else { *pos=I[en]; return y; } }; x=st+(en-st)/2; if(memcmp(old+I[x],_new,MIN(oldsize-I[x],newsize))<0) { return search(I,old,oldsize,_new,newsize,x,en,pos); } else { return search(I,old,oldsize,_new,newsize,st,x,pos); };}static void offtout(off_t x,u_char *buf){ off_t y; if(x<0) y=-x; else y=x; buf[0]=y%256;y-=buf[0]; y=y/256;buf[1]=y%256;y-=buf[1]; y=y/256;buf[2]=y%256;y-=buf[2]; y=y/256;buf[3]=y%256;y-=buf[3]; y=y/256;buf[4]=y%256;y-=buf[4]; y=y/256;buf[5]=y%256;y-=buf[5]; y=y/256;buf[6]=y%256;y-=buf[6]; y=y/256;buf[7]=y%256; if(x<0) buf[7]|=0x80;}int diff(int argc,char *argv[]){ int fd; u_char *old,*_new; off_t oldsize,newsize; off_t *I,*V; off_t scan,pos,len; off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc; off_t s,Sf,lenf,Sb,lenb; off_t overlap,Ss,lens; off_t i; off_t dblen,eblen; u_char *db,*eb; u_char buf[8]; u_char header[32]; FILE * pf; BZFILE * pfbz2; int bz2err; if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ //org: //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]); //new: //Read in chunks, don't rely on read always returns full data! if(((fd=open(argv[1],O_RDONLY|O_BINARY|O_NOINHERIT,0))<0) || ((oldsize=lseek(fd,0,SEEK_END))==-1) || ((old=(u_char*)malloc(oldsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0)) err(1,"%s",argv[1]); int r=oldsize; while (r>0 && (i=read(fd,old+oldsize-r,r))>0) r-=i; if (r>0 || close(fd)==-1) err(1,"%s",argv[1]); if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL) || ((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL); qsufsort(I,V,old,oldsize); free(V); /* Allocate newsize+1 bytes instead of newsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ //org: //if(((fd=open(argv[2],O_RDONLY,0))<0) || // ((newsize=lseek(fd,0,SEEK_END))==-1) || // ((_new=malloc(newsize+1))==NULL) || // (lseek(fd,0,SEEK_SET)!=0) || // (read(fd,_new,newsize)!=newsize) || // (close(fd)==-1)) err(1,"%s",argv[2]); //new: //Read in chunks, don't rely on read always returns full data! if(((fd=open(argv[2],O_RDONLY|O_BINARY|O_NOINHERIT,0))<0) || ((newsize=lseek(fd,0,SEEK_END))==-1) || ((_new=(u_char*)malloc(newsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0)) err(1,"%s",argv[2]); r=newsize; while (r>0 && (i=read(fd,_new+newsize-r,r))>0) r-=i; if (r>0 || close(fd)==-1) err(1,"%s",argv[1]); if(((db=(u_char*)malloc(newsize+1))==NULL) || ((eb=(u_char*)malloc(newsize+1))==NULL)) err(1,NULL); dblen=0; eblen=0; /* Create the patch file */ //org: //if ((pf = fopen(argv[3], "w")) == NULL) //new: //if((fd=open(argv[3],O_CREAT|O_TRUNC|O_WRONLY|O_BINARY|O_NOINHERIT,0666))<0) if ((pf = fopen(argv[3], "wb")) == NULL) err(1,"%s",argv[3]); /* Header is 0 8 "BSDIFF40" 8 8 length of bzip2ed ctrl block 16 8 length of bzip2ed diff block 24 8 length of new file */ /* File is 0 32 Header 32 ?? Bzip2ed ctrl block ?? ?? Bzip2ed diff block ?? ?? Bzip2ed extra block */ memcpy(header,"BSDIFF40",8); offtout(0, header + 8); offtout(0, header + 16); offtout(newsize, header + 24); if (fwrite(header, 32, 1, pf) != 1) err(1, "fwrite(%s)", argv[3]); /* Compute the differences, writing ctrl as we go */ if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err); scan=0;len=0; lastscan=0;lastpos=0;lastoffset=0; while(scan
oldscore+8)) break; if((scan+lastoffset
Sf*2-lenf) { Sf=s; lenf=i; }; }; lenb=0; if(scan
=lastscan+i)&&(pos>=i);i++) { if(old[pos-i]==_new[scan-i]) s++; if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; }; }; }; if(lastscan+lenf>scan-lenb) { overlap=(lastscan+lenf)-(scan-lenb); s=0;Ss=0;lens=0; for(i=0;i
Ss) { Ss=s; lens=i+1; }; }; lenf+=lens-overlap; lenb-=lens; }; for(i=0;i
GetStringUTFChars(old_path, NULL)); char * newfile = (char *)(env->GetStringUTFChars(new_path, NULL)); char * patchfile = (char *)(env->GetStringUTFChars(patch_path, NULL)); //定义参数 char *argv[4]; argv[0] = "renzhenming"; argv[1]=oldfile; argv[2]= newfile; argv[3]=patchfile; diff(argc, argv); env->ReleaseStringUTFChars(old_path, oldfile); env->ReleaseStringUTFChars(new_path, newfile); env->ReleaseStringUTFChars(patch_path, patchfile);}

然后生成动态库,放到eclipse web工程目录下,写工程调用生成差分包

public class UpdateTest {    public static void main(String[] args) {        DiffUtils.diff(ConstantsWin.OLD_APK_PATH, ConstantsWin.NEW_APK_PATH, ConstantsWin.PATCH_PATH);        System.out.println("差分包生成成功");    }}

2.客户端合并差分包生成新包

创建native方法生成头文件

public class BsPatch {    /**     * 合并     *      * @param oldfile     * @param newfile     * @param patchfile     */    public native static void patch(String oldfile, String newfile, String patchfile);    static{        System.loadLibrary("bspatch");    }    }
/* DO NOT EDIT THIS FILE - it is machine generated */#include 
/* Header for class com_example_ndk_patch_utils_BsPatch */#ifndef _Included_com_example_ndk_patch_utils_BsPatch#define _Included_com_example_ndk_patch_utils_BsPatch#ifdef __cplusplusextern "C" {#endif/* * Class: com_example_ndk_patch_utils_BsPatch * Method: patch * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */JNIEXPORT void JNICALL Java_com_example_ndk_1patch_utils_BsPatch_patch (JNIEnv *, jclass, jstring, jstring, jstring);#ifdef __cplusplus}#endif#endif

创建jni目录,将头文件复制进去,添加bspatch.c文件和相关的bzip文件,注意,Android系统是基于Linux的,所以这里的文件需要是Linux版本的

img_d210683a07e7c5d1b7ebcaba6dd0b99c.png
8267671.png

然后在右键add native support,然后在添加ndk的相关头文件的目录

D:\application\java\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.8\includeD:\application\java\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.8\include-fixedD:\application\java\android-ndk-r10e\platforms\android-18\arch-arm\usr\include

然后似乎就没有问题了,这里遇到过问题,有可能是add native和添加ndk目录的时机不对,导致c文件中或者头文件中的属性类之类的爆红,显示无法resolve,不知道

何故,不过后来按上边的顺序就可以了,也是坑

bspathc中添加合并的代码,注意一些相关头文件的引入

/*- * Copyright 2003-2005 Colin Percival * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted providing that the following conditions  * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#if 0__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $");#endif#include "com_example_ndk_patch_utils_BsPatch.h"#include "bzip2/bzlib.c"#include "bzip2/crctable.c"#include "bzip2/compress.c"#include "bzip2/decompress.c"#include "bzip2/randtable.c"#include "bzip2/blocksort.c"#include "bzip2/huffman.c"#include 
#include
#include
#include
#include
#include
static off_t offtin(u_char *buf){ off_t y; 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; return y;}int bspatch_main(int argc,char * argv[]){ FILE * f, * cpf, * dpf, * epf; BZFILE * cpfbz2, * dpfbz2, * epfbz2; int cbz2err, dbz2err, ebz2err; int fd; ssize_t oldsize,newsize; ssize_t bzctrllen,bzdatalen; u_char header[32],buf[8]; u_char *old, *new; off_t oldpos,newpos; off_t ctrl[3]; off_t lenread; off_t i; 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: 0 8 "BSDIFF40" 8 8 X 16 8 Y 24 8 sizeof(newfile) 32 X bzip2(control block) 32+X Y bzip2(diff block) 32+X+Y ??? bzip2(extra block) with control block a set of triples (x,y,z) meaning "add x bytes from oldfile to x bytes from the diff block; copy y bytes from the extra block; 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) 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
=0) && (oldpos+i
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); return 0;}JNIEXPORT void JNICALL Java_com_example_ndk_1patch_utils_BsPatch_patch (JNIEnv *env, jclass jcls, jstring oldfile_jstr, jstring newfile_jstr, jstring patchfile_jstr){ int argc = 4; char *oldfile = (char*)(*env)->GetStringUTFChars(env,oldfile_jstr,NULL); char *newfile = (char*)(*env)->GetStringUTFChars(env,newfile_jstr,NULL); char *patchfile = (char*)(*env)->GetStringUTFChars(env,patchfile_jstr,NULL); char *argv[4]; argv[0] = "bspatch"; argv[1] = oldfile; argv[2] = newfile; argv[3] = patchfile; bspatch_main(argc,argv); (*env)->ReleaseStringUTFChars(env,oldfile_jstr,oldfile); (*env)->ReleaseStringUTFChars(env,newfile_jstr,newfile); (*env)->ReleaseStringUTFChars(env,patchfile_jstr,patchfile);}

其他文件上源码好了,自己看吧,我是懒得写了,这个笔记的过程,并不是一步一步就可以实现的,而是我实现之后按照记忆写的,有些地方肯定还有坑

img_c6d616d2628fe1f94ee8e7654e710502.png
8522718.png

MainActivity.java

package com.example.ndk_patch;import java.io.File;import com.example.ndk_patch.utils.ApkUtils;import com.example.ndk_patch.utils.BsPatch;import com.example.ndk_patch.utils.Constants;import com.example.ndk_patch.utils.DownloadUtils;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.util.Log;import android.widget.Toast;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        new Handler().postDelayed(new Runnable() {                        @Override            public void run() {                new ApkUpdateTask().execute();                            }        }, 2000);            }    class ApkUpdateTask extends AsyncTask
{ @Override protected Boolean doInBackground(Void... params) { try { System.out.println("开始合并"); File patchFile = new File(Constants.PATCH_FILE_PATH); if (patchFile.exists()) { //获取当前应用的apk文件/data/app/app String oldfile = ApkUtils.getSourceApkPath(MainActivity.this, getPackageName()); //2.合并得到最新版本的APK文件 String newfile = Constants.NEW_APK_PATH; String patchfile = patchFile.getAbsolutePath(); BsPatch.patch(oldfile, newfile, patchfile); }else{ return false; } } catch (Exception e) { e.printStackTrace(); return false; } return true; } @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); //3.安装 if(result){ System.out.println("合并成功"); Toast.makeText(MainActivity.this, "合并成功,您正在进行无流量更新", Toast.LENGTH_SHORT).show(); ApkUtils.installApk(MainActivity.this, Constants.NEW_APK_PATH); } } }}

ApkUtils.java

package com.example.ndk_patch.utils;import android.content.Context;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.net.Uri;import android.text.TextUtils;public class ApkUtils {    public static boolean isInstalled(Context context, String packageName) {        PackageManager pm = context.getPackageManager();        boolean installed = false;        try {            pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);            installed = true;        } catch (Exception e) {            e.printStackTrace();        }        return installed;    }    /**     * 获取已安装Apk文件的源Apk文件     * 如:/data/app/my.apk     *      * @param context     * @param packageName     * @return     */    public static String getSourceApkPath(Context context, String packageName) {        if (TextUtils.isEmpty(packageName))            return null;        try {            ApplicationInfo appInfo = context.getPackageManager()                    .getApplicationInfo(packageName, 0);            return appInfo.sourceDir;        } catch (NameNotFoundException e) {            e.printStackTrace();        }        return null;    }    /**     * 安装Apk     *      * @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);    }}

BsPatch.java

package com.example.ndk_patch.utils;public class BsPatch {    /**     * 合并     *      * @param oldfile     * @param newfile     * @param patchfile     */    public native static void patch(String oldfile, String newfile, String patchfile);    static{        System.loadLibrary("bspatch");    }    }

Constants.java

import java.io.File;import android.os.Environment;public class Constants {    public static final String SD_CARD = Environment.getExternalStorageDirectory() + File.separator;    public static final String NEW_APK_PATH = SD_CARD+"apk_new.apk";    public static final String PATCH_FILE = "apk.patch";    public static final String PATCH_FILE_PATH = SD_CARD+PATCH_FILE;    }

转载地址:http://bkonl.baihongyu.com/

你可能感兴趣的文章
mybatis缓存之FifoCache
查看>>
static const 修改函数 功能
查看>>
npm 常用命令以及 npm scripts
查看>>
tomcat的最大线程数、最大排队数多少合适
查看>>
安装snmp无法安装依赖包net-snmp-libs = 1:5.3.2.2-20.el5
查看>>
JVisualVM之GC插件+错误"not supported for this jvm"+命令jstatd
查看>>
wp7上启动器使用方法
查看>>
基于虚拟用户的邮件系统
查看>>
TODO:火热的集福,我这样看
查看>>
Linux进程和任务计划管理
查看>>
fsck修复命令
查看>>
活动目录管理的四个复杂性
查看>>
A Tale of Five Editors 之Wily
查看>>
Python Django shell 调试
查看>>
Vim 实用技术常用插件
查看>>
RHEL-用户基础-重定向
查看>>
awstats 安装备忘
查看>>
使用CocoaLumberjack的一些问题记录
查看>>
Nginx 服务控制脚本
查看>>
java.lang.NullPointerException pstmt = conn.prepareStatement(sql)报错
查看>>