版權聲明:本文爲博主原創文章,未經博主允許不得轉載。
Android增量更新簡單描述:
簡單的說,就是在有一箇舊版本A的情況下,想在這個基礎上更新一個新版本B。那麼,我們不需要下載整個B,只需要下載A與B的差分包。將差分包下載到本地後,與舊版本A整合爲一個新的apk,這個apk大小與內容與新版本B完全一致,這就是增量更新。
假如,A的大小是5M,B的大小是8M,那麼差分包的大小S=(8-5)+差異文件的依賴(如上下文)。差分包的大小會大於3M。
Android增量更新如何實現:
這裏我們有用到一對工具,bsdiff.exe、bspatch.exe。可在後續的源碼中下載。
用工具,很容易達到這個效果,有兩個步驟:
假如,你將這對工具放置在如下路徑下:D:\zhao.yang\Downloads\test_UpdateSome\test\bsdiff4.3-win32,那麼,請先打開cmd,輸入命令: cd D:\zhao.yang\Downloads\test_UpdateSome\test\bsdiff4.3-win32 ,按Enter後,再輸入命令:cd d: ,進入該目錄下。
(1)新舊版本生成差分包
命令格式:bsdiff.exe 舊版本apk路徑 新版本apk路徑 差分包存儲路徑
按這命令格式,我們寫出如下命令:
bsdiff.exe D:\Java\workspace\ApkPatchAndroidDemo\bin\ApkPatchAndroid_old.apk D:\JAVA\workspace\ApkPatchAndroidDemo\bin\ApkPatchAndroid_new.apk D:\JAVA\workspace\ApkPatchAndroidDemo\bin\test.patch
即可得到相應的差分包test.patch。
(2)整合差分包與舊版本apk
命令格式:bspatch.exe 舊版本apk路徑 新版本apk路徑 差分包存儲路徑
按這命令格式,我們寫出如下命令:
bspatch.exe D:\JAVA\workspace\ApkPatchAndroidDemo\bin\ApkPatchAndroid_old.apk D:\JAVA\workspace\ApkPatchAndroidDemo\bin\ApkPatchAndroid_2new.apk D:\JAVA\workspace\ApkPatchAndroidDemo\bin\test.patch
經過以上兩個步驟,我們完成了差分包生成,差分包與舊版本apk的整合,你會發現最後得到的apk就是你需要的apk。到這裏,用工具演示的增量更新的步驟就完成了。但是,在android中,當你在做android的增量更新時,是需要源碼實現的。
下方就介紹如何實現:
Android端整合差分包與舊版本apk的實現
這裏暫時將舊版本apk、差分包都放在SD卡的根目錄下。
這裏引入了一位高手寫的開源源碼,引用JNI實現整合。在主界面上無需寫什麼代碼,只要根據函數參數要求填入參數即可:
- package com.example.apkpatch2newapk;
- import java.io.File;
- import com.dodola.patcher.utils.AppUtils;
- import android.os.Bundle;
- import android.os.Environment;
- import android.app.Activity;
- import android.view.Menu;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- String oldApkPathString=Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"ApkPatchAndroid_old.apk";
- String newApkPathString=Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"ApkPatchAndOld2New.apk";
- String patchPathString=Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"test.patch";
- static {
- // 調用.so文件,引入打包庫
- System.loadLibrary("Patcher");
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Button btnButton=(Button)findViewById(R.id.btn);
- btnButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- AppUtils.patcher(oldApkPathString, newApkPathString, patchPathString);
- }
- });
- }
- }
package com.example.apkpatch2newapk;
import java.io.File;
import com.dodola.patcher.utils.AppUtils;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
String oldApkPathString=Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"ApkPatchAndroid_old.apk";
String newApkPathString=Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"ApkPatchAndOld2New.apk";
String patchPathString=Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"test.patch";
static {
// 調用.so文件,引入打包庫
System.loadLibrary("Patcher");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnButton=(Button)findViewById(R.id.btn);
btnButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
AppUtils.patcher(oldApkPathString, newApkPathString, patchPathString);
}
});
}
}
重點還在於patcher這個函數中。
- package com.dodola.patcher.utils;
- import java.io.File;
- import android.content.Context;
- import android.content.Intent;
- import android.net.Uri;
- /**
- *應用程序的工具類
- * @author Administrator
- *
- */
- public class AppUtils {
- /**
- * 安裝一個應用程序
- * @param context
- * @param apkfile
- */
- public static void installApplication(Context context,File apkfile){
- /* <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:scheme="content" />
- <data android:scheme="file" />
- <data android:mimeType="application/vnd.android.package-archive" />*/
- Intent intent = new Intent();
- intent.setAction("android.intent.action.VIEW");
- intent.addCategory("android.intent.category.DEFAULT");
- // intent.setType("application/vnd.android.package-archive");
- // intent.setData(Uri.fromFile(apkfile));
- intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
- context.startActivity(intent);
- }
- /**
- * 調用.so庫中的方法,合併apk
- *
- * @param old
- * 舊Apk地址
- * @param newapk
- * 新apk地址(名字)
- * @param patch
- * 增量包地址
- */
- public static native void patcher(String old, String newapk, String patch);
- }
package com.dodola.patcher.utils;
import java.io.File;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
/**
*應用程序的工具類
* @author Administrator
*
*/
public class AppUtils {
/**
* 安裝一個應用程序
* @param context
* @param apkfile
*/
public static void installApplication(Context context,File apkfile){
/* <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" />
<data android:scheme="file" />
<data android:mimeType="application/vnd.android.package-archive" />*/
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
// intent.setType("application/vnd.android.package-archive");
// intent.setData(Uri.fromFile(apkfile));
intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
context.startActivity(intent);
}
/**
* 調用.so庫中的方法,合併apk
*
* @param old
* 舊Apk地址
* @param newapk
* 新apk地址(名字)
* @param patch
* 增量包地址
*/
public static native void patcher(String old, String newapk, String patch);
}
整合的開源源碼內容,主要是jni實現的c/c++代碼,感興趣的可以在下方的源碼下載中看。
注意:
(1)不熟悉jni的同學,這裏要注意一點,jni的方法與包名是相關的,因此如果想用這個方法,最方便的是把包名也一起復制過去即可。
(2)該方法是需要用到NDK環境的,如果沒有這個環境,可以到如下地址下載:
NDK下載鏈接:http://pan.baidu.com/s/1bn0H75P 密碼:6cje
(3)可在Window-Preferences-NDK中配置下載的NDK。
源碼與工具下載:
http://download.csdn.net/detail/yangzhaomuma/9448393
- 頂
- 1
- 踩
- 0
我的同類文章
- •Java(Android)回調函數詳解2016-07-22
- •Android之本地緩存——LruCache(內存緩存)與DiskLruCache(硬盤緩存)統一框架2016-07-02
- •Android之註解的使用——綁定android控件2016-04-18
- •Android監聽——回調模式與觀察者模式2016-03-24
- •Android圖片處理之高斯模糊示例——仿微信朋友圈照片模糊效果2016-02-01
- •Android之數據庫—— 一個可配置的簡易框架2016-07-05
- •Android(Java)之多線程結果返回——Future 、FutureTask、Callable、Runnable2016-06-20
- •Android解析——json解析爲javabean2016-03-28
- •Android進程間通訊——多進程共用SharedPreferences2016-02-22
- •Android遠程接口之AIDL——Parcelable、in、out、inout簡例2016-01-25