增量更新
下载 的差分工具
去官网下载 bsdiff http://www.daemonology.net/bsdiff/
bsdiff 下载
下载bzip https://sourceforge.net/projects/bzip2/files/latest/download
bzip下载
windows的话 网上有人编译好的文件 直接用就可以
linux 可以去官网下载源码 自己编译
bsdiff .exe 是 差分工具 --生成差分包(补丁包)的
bspath.exe 是 合并工具 – 是将补丁包和旧的包合并成一个新的安装包
差分命令
//差分命令
bsdiff.exe appold.apk appnew.apk patch
//合并命令
bspatch.exe appold.apk appnew.apk patch
创建一个NDK 项目
在android studio 中 直接new 就好了 但是要保证 安装 ndk
将bsdiff 中的 bspatch.c 和 bzip源码中的库 复制到自己的项目中去
这个在bzip源码中
这个在bsdiff库里面
复制到自己项目中是这样的
代码部分
创建native方法
/**
* @param oldApk 老板本
* @param patch 差分包
* @param output 新包
* @return
*/
public native String bsPatch(String oldApk, String patch, String output);
如果你安装了 Android NDK support 这个插件 可以直接使用快捷键 alt+回车 在native-lib.cpp 文件中生成方法
这里面的patch_mian 方法 是 bspatch.c 中的main 方法 将他的名字修改后 引入到native-lib.cpp 文件中使用
引入的方法
extern "C" {
extern int patch_main(int argc, char *argv[]);
}
#include <jni.h>
#include <string>
extern "C" {
extern int patch_main(int argc, char *argv[]);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_text_MainActivity_bsPatchApk(JNIEnv *env, jobject thiz, jstring old_apk_,
jstring path_, jstring output_) {
const char *oldApk = env->GetStringUTFChars(old_apk_, 0);
const char *patch = env->GetStringUTFChars(path_, 0);
const char *output = env->GetStringUTFChars(output_, 0);
char *argv[4] = {const_cast<char *>(""), const_cast<char *>(oldApk),
const_cast<char *>(output),
const_cast<char *>(patch)};
int rec = patch_main(4, argv);
env->ReleaseStringUTFChars(old_apk_, oldApk);
env->ReleaseStringUTFChars(path_, patch);
env->ReleaseStringUTFChars(output_, output);
return rec;
}
将bzip文件夹下面的库引入到文件中 在CMakeLists.txt 文件中操作
将文件引入到
cmake_minimum_required(VERSION 3.4.1)
file(GLOB bzip_s ${CMAKE_SOURCE_DIR}/bzip/*.c)#将文件引入进来
#设置本地的动态库用来编译生成.so
add_library( # Sets the name of the library.
native-lib#模块名
SHARED#动态
native-lib.cpp
bspatch.c
${bzip_s})#源文件 在这里添加进项目中
find_library( # Sets the name of the path variable.
log-li
log)
target_link_libraries( # Specifies the target library.
native-lib
${log-lib})
在MainActivity这样写
public class MainActivity extends AppCompatActivity {
private TextView tversion;
private String oldName = "old.apk";
private String newName = "new.apk";
//引入本地库
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tversion = findViewById(R.id.version);
tversion.setText(BuildConfig.VERSION_NAME);
//添加权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] parms = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (checkSelfPermission(parms[0]) == PackageManager.PERMISSION_DENIED) {
requestPermissions(parms, 200);
}
}
}
/**
* 点击事件
*
* @param view
*/
public void toGetApk(View view) {
hbApk();
}
@SuppressLint("StaticFieldLeak")
private void hbApk() {
new AsyncTask<Void, Void, File>() {
/**
* 耗时
* @param voids
* @return
*/
@Override
protected File doInBackground(Void... voids) {
String oldapk = getApplication().getApplicationInfo().sourceDir;
//从网络行下载的差分包在本地的路径
String patch = new File(Environment.getExternalStorageDirectory(), "a.patch").getAbsolutePath();
//放置最新包的路径
String output = creatNewApk(newName).getAbsolutePath();
//调用native方法
bsPatchApk(oldapk, patch, output);
return new File(output);
}
/**
* 耗时操作完成之后 进这个方法
* @param file
*/
@Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
UriParseUtils.installApk(MainActivity.this, file);
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}.execute();
}
/**
* 创建路径
*
* @return
*/
private File creatNewApk(String name) {
File newapk = new File(Environment.getExternalStorageDirectory(), name);
try {
if (!newapk.exists()) {
newapk.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
return newapk;
}
/**
* @param oldApk 老板本
* @param path 差分包
* @param output 新包
* @return
*/
public native int bsPatchApk(String oldApk, String path, String output);
@Override
protected void onRestart() {
super.onRestart();
tversion.setText(BuildConfig.VERSION_NAME);
}
}
主要就是不要忘记添加 储存权限