java bsdiff_Android差分包生成和合成新包-bsdiff

本文介绍了如何使用Java在Android环境下利用bsdiff库生成差分包,并结合老版本APK合成新版本APK。详细步骤包括复制Asset中新旧版本APK到SD卡、生成差分增量包、合成新版本APK,以及电脑上使用bsdiff工具生成差分包的过程。
摘要由CSDN通过智能技术生成

测试验证环境:

1d69b3ade53a?t=1493709593357

Paste_Image.png

项目目录结构:

1d69b3ade53a?t=1493709593357

Paste_Image.png

build.gradle文件:

 
 

apply plugin: 'com.android.application'

android {

compileSdkVersion 23

buildToolsVersion '23.0.1'

defaultConfig {

applicationId "com.yuyh.inc.update"

minSdkVersion 14

targetSdkVersion 23

versionCode 1

versionName "1.0"

ndk{

moduleName "ApkPatchLibrary"

abiFilters "armeabi", "armeabi-v7a", "x86"

}

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

}

sourceSets {

main {

jni.srcDirs = ['src/main/jni', 'src/main/jni/']

// jniLibs.srcDirs = ['libs'] // 若不想编译jni代码,可直接引用so库,ndk编译相关脚本注释掉

}

}

}

dependencies {

compile fileTree(include: ['*.jar'], dir: 'libs')

testCompile 'junit:junit:4.12'

compile 'com.android.support:appcompat-v7:23.+'

}

核心代码:

 
 

package com.yyh.lib;

import android.app.Activity;

import android.content.Intent;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.widget.ProgressBar;

import android.widget.Toast;

import com.yuyh.inc.update.R;

import com.yyh.lib.bsdiff.DiffUtils;

import com.yyh.lib.bsdiff.PatchUtils;

import com.yyh.lib.utils.FileUtils;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

public class MainActivity extends Activity {

private ProgressBar loadding;

// 成功

private static final int WHAT_SUCCESS = 1;

// 失败

private static final int WHAT_FAIL_PATCH = 0;

/**

* 老版本apk

*/

private String oldApkDir = Environment.getExternalStorageDirectory().toString() + "/bsdiff_old.apk";

/**

* 新版本apk

*/

private String newApkDir = Environment.getExternalStorageDirectory().toString() + "/bsdiff_new_build.apk";

/**

* 根据新老版本差分包生成的新版本apk

*/

private String destDir2 = Environment.getExternalStorageDirectory().toString() + "/bsdiff_new.apk";

/**

* 新老版本的增量更新包

*/

private String oldToNewPatchDir = Environment.getExternalStorageDirectory().toString() + "/old-to-new.patch";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

loadding = (ProgressBar) findViewById(R.id.loadding);

}

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 0:

Toast.makeText(getApplicationContext(), "复制成功", Toast.LENGTH_SHORT).show();

break;

case 1:

Toast.makeText(getApplicationContext(), "复制失败", Toast.LENGTH_SHORT).show();

break;

case 2:

Toast.makeText(getApplicationContext(), "生成增新包成功", Toast.LENGTH_SHORT).show();

break;

case 3:

Toast.makeText(getApplicationContext(), "生成增新包失败", Toast.LENGTH_SHORT).show();

break;

case 4:

Toast.makeText(getApplicationContext(), "合成新版本成功", Toast.LENGTH_SHORT).show();

break;

case 5:

Toast.makeText(getApplicationContext(), "合成新版本失败", Toast.LENGTH_SHORT).show();

break;

default:

break;

}

}

};

/**

* 复制文件

* @param view

*/

public void copy(View view) {

loadding.setVisibility(View.VISIBLE);

new CopyTask().execute(oldApkDir, "bsdiff_old.apk", newApkDir, "bsdiff_new.apk");

}

/**

* 生成差分增量包

* @param view

*/

public void bsdiff(View view) {

loadding.setVisibility(View.VISIBLE);

new DiffTask().execute();

}

/**

* 合成新版本

* @param view

*/

public void bspatch(View view) {

loadding.setVisibility(View.VISIBLE);

new PatchTask().execute();

}

/**

* 安装老版本

* @param view

*/

public void installOld(View view) {

install(oldApkDir);

}

/**

* 安装新版本

* @param view

*/

public void installNew(View view) {

install(destDir2);

}

/**

* 复制文件线程

*/

private class CopyTask extends AsyncTask {

@Override

protected Integer doInBackground(String... params) {

for (int i = 0; i < params.length; i += 2) {

try {

File file = new File(params[i]);

if (!file.exists())

FileUtils.createFile(file);

InputStream is;

OutputStream os = new FileOutputStream(params[i]);

is = getAssets().open(params[i + 1]);

byte[] buffer = new byte[1024];

int length = is.read(buffer);

while (length > 0) {

os.write(buffer, 0, length);

length = is.read(buffer);

}

os.flush();

is.close();

os.close();

} catch (Exception e) {

handler.obtainMessage(1).sendToTarget();

return null;

}

}

handler.obtainMessage(0).sendToTarget();

return null;

}

@Override

protected void onPostExecute(Integer integer) {

super.onPostExecute(integer);

loadding.setVisibility(View.GONE);

}

}

/**

* 生成差分包线程

*

* @author yuyuhang

* @date 2016-1-25 下午12:24:34

*/

private class DiffTask extends AsyncTask {

@Override

protected Integer doInBackground(String... params) {

try {

int result = DiffUtils.getInstance().genDiff(oldApkDir, newApkDir, oldToNewPatchDir);

if (result == 0) {

handler.obtainMessage(2).sendToTarget();

return WHAT_SUCCESS;

} else {

handler.obtainMessage(3).sendToTarget();

return WHAT_FAIL_PATCH;

}

} catch (Exception e) {

e.printStackTrace();

}

return WHAT_FAIL_PATCH;

}

@Override

protected void onPostExecute(Integer integer) {

super.onPostExecute(integer);

loadding.setVisibility(View.GONE);

}

}

/**

* 差分包合成APK线程

*

* @author yuyuhang

* @date 2016-1-25 下午12:24:34

*/

private class PatchTask extends AsyncTask {

@Override

protected Integer doInBackground(String... params) {

try {

int result = PatchUtils.getInstance().patch(oldApkDir, destDir2, oldToNewPatchDir);

if (result == 0) {

handler.obtainMessage(4).sendToTarget();

return WHAT_SUCCESS;

} else {

handler.obtainMessage(5).sendToTarget();

return WHAT_FAIL_PATCH;

}

} catch (Exception e) {

e.printStackTrace();

}

return WHAT_FAIL_PATCH;

}

@Override

protected void onPostExecute(Integer integer) {

super.onPostExecute(integer);

loadding.setVisibility(View.GONE);

}

}

/**

* 安装软件

* @param dir

*/

private void install(String dir) {

String command = "chmod 777 " + dir;

Runtime runtime = Runtime.getRuntime();

try {

runtime.exec(command); // 可执行权限

} catch (IOException e) {

e.printStackTrace();

}

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

intent.setDataAndType(Uri.parse("file://" + dir), "application/vnd.android.package-archive");

startActivity(intent);

}

/*

public void appList(View view) {

Intent intent = new Intent(this, ApplistActivity.class);

startActivity(intent);

}

*/

}

1、软件运行效果图

1d69b3ade53a?t=1493709593357

Paste_Image.png

2、将Asset中的新旧版本复制到sd卡上

1d69b3ade53a?t=1493709593357

Paste_Image.png

3、安装旧版本,效果图

1d69b3ade53a?t=1493709593357

Paste_Image.png

4、差分生成增量更新包 old-to-new.patch

1d69b3ade53a?t=1493709593357

Paste_Image.png

5、根据old-to-new.patch差分增量包生成新版本的安装包bsdiff_new.apk

1d69b3ade53a?t=1493709593357

Paste_Image.png

1d69b3ade53a?t=1493709593357

Paste_Image.png

6、安装合成的新版本bsdiff_new.apk

1d69b3ade53a?t=1493709593357

Paste_Image.png

1d69b3ade53a?t=1493709593357

Paste_Image.png

到此移动端的生成差分包和合成新版本就完成了。

但是实际中,不会在移动端来生成差分更新包,而是生成差分包之后移动端下载,然后合成新的安装包,然后进行更新。

所以可以通过下面的方式在电脑上生成差分新增包:

工具下载:http://download.csdn.net/detail/suijing/9829716

1d69b3ade53a?t=1493709593357

Paste_Image.png

通过cmd打开命令窗口:

进入到目录中

(1)生成差量更新包文件old-to-new.patch:

bsdiff old.apk new.apk old-to-new.patch

这里生成的增量包 old-to-new.patch就可以用来跟老版本生成新的安装包了

1d69b3ade53a?t=1493709593357

Paste_Image.png

(2)根据差量更新包old-to-new.patch生成新版本new2.apk :

bspatch old.apk new2.apk old-to-new.patch

1d69b3ade53a?t=1493709593357

Paste_Image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值