日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux android sdk gengxinman,Android 实现增量更新

發(fā)布時間:2023/12/4 linux 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux android sdk gengxinman,Android 实现增量更新 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、概述

增量更新相較于全量更新的好處不言而喻,利用差分算法獲得1.0版本到2.0版本的差分包,這樣在安裝了1.0的設備上只要下載這個差分包就能夠完成由1.0-2.0的更新。比如:

存在一個1.0版本的apk

apk1.png

然后需要升級到2.0版本,而2.0版本的apk為

apk2.png

這樣如果進行全量更新則需要下載完整的76.6M大小的apk文件,進行安裝。而如果使用增量更新則只需要下載如下 50.7M的差分包。

patch.png

下載數(shù)據(jù)減少了26M。這樣做的好處不僅僅在于對于流量的節(jié)省。對于用戶來說現(xiàn)在流量可能并不值錢,或者使用wifi再進行更新,但是從下載時間能夠得到一個良好的優(yōu)化,同時也減小了服務器的壓力。

二、實現(xiàn)

需要實現(xiàn)增量更新,現(xiàn)在有各種開源的制作與合并差分包的開源庫,比如:bsdiff、hdiff等等。因此我們只需要獲得源碼來使用即可。

下載完成后解壓:

bsdiff源碼.png

bsdiff: 比較兩個文件的二進制數(shù)據(jù),生成差分包

bspatch: 合并舊的文件與差分包,生成新文件

執(zhí)行make

很顯然,bspatch我們需要在Android環(huán)境下來執(zhí)行,而bsdiff 一般會在你的存儲服務器當中執(zhí)行即電腦環(huán)境下執(zhí)行(win或linux)

切到解壓后的目錄,然后執(zhí)行make:

Makefile:13: *** missing separator. Stop.

這時會報錯,需要修改Makefile文件,將install:下面的if,endif添加一個縮進:

install:

${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin

.ifndef WITHOUT_MAN

${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1

.endif

#上面這段makefile片段顯然有問題

#因此需要修改為:

install:

${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin

.ifndef WITHOUT_MAN

${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1

.endif

#也就是在 `.if` 和 `.endif` 前加一個 tab

unknown type name 'u_char'; did you mean 'char'static off_t offtin(u_char *buf)

然后,重新執(zhí)行make:

錯誤很明顯,找不到u_char等,因為缺少了頭文件

在bspatch.c文件中加入

#include

再次make就好了

no file found bzlib.h之類的錯誤

如果出現(xiàn)找不到bzip2 no file found bzlib.h之類的錯誤,則需要先安裝bzip2:

Ubuntu:

apt install libbz2-dev

Centos:

yum -y install bzip2-devel.x86_64

Mac:

brew install bzip2

最后執(zhí)行make后沒有問題了,就會生成兩個bsdiff和bspatch的可執(zhí)行文件

bsdiff和bspatch的工具的使用

首先我們準備兩個apk,old.apk和new.apk,你可以自己隨便寫個項目,先運行一次拿到生成的apk作為old.apk;然后修改些代碼,或者加一些功能,再運行一次生成new.apk;

生成增量文件

./bsdiff old.apk new.apk patch

這樣就生成了一個增量文件patch

增量文件和old.apk合并成新的apk

./bspatch old.apk new2.apk patch

這樣就生成一個new2.apk

我們可以使用md5來查看new.apk和new2.apk兩個文件的md5值,

md5值的比較

三、android代碼中實現(xiàn)bspatch合并

將bspatch.c文件考入到項目的cpp目錄下,因為其還需要bzip2依賴,所以將下載好的bzip2的一些源碼也考入到項目中,

從下載的bzip2里的Makefile中的OBJS可以看出需要7個源文件文件,因此將這對應的源文件考入到抗美中,然后在將依賴的.h文件也考入項目中

最終要考入的文件如下:

在項目的CMakeLists.txt文件中把bspatch.c和bzip項目源文件加入其中

file(GLOB bzip_source src/main/cpp/bzip/*.c)

add_library(

native-lib

SHARED

src/main/cpp/native-lib.cpp

src/main/cpp/bspatch.c

${bzip_source})

此時執(zhí)行AS的Build下的Make project,發(fā)現(xiàn)會報錯

明明考入的有bzlib.h這個文件,為哈還是報錯呢?,其實這個是因為bspatch.c里是以#include 這種形式引入bzlib.h的,我們可以將其引入方式改為#include "bzip/bzlib.h"就可以了,但在這里我們用一種不修改源碼的方式解決,就是在CMakeLists.txt中加入一句include_directories(src/main/cpp/bzip)就可以了。

下面是具體實現(xiàn)

MainActivity.java

public class MainActivity extends AppCompatActivity {

static {

System.loadLibrary("native-lib");

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

TextView version = (TextView) findViewById(R.id.tv_version);

version.setText(BuildConfig.VERSION_NAME);

}

/**

* native方法 使用路徑為oldapk的apk與路徑為patch的補丁包,合成新的apk,并存儲于output

* @param oldapk 當前運行的apk

* @param patch 差分包

* @param output 合成后的新的apk

*/

native void bspatch(String oldapk,String patch,String output);

public void onUpdate(View view) {

new MyAsyncTask().execute();

}

private class MyAsyncTask extends AsyncTask{

@Override

protected File doInBackground(Void... voids) {

//1、合成apk

String old = getApplication().getApplicationInfo().sourceDir;

bspatch(old,"/sdcard/patch","/sdcard/new.apk");

return new File("/sdcard/new.apk");

}

@Override

protected void onPostExecute(File file) {

super.onPostExecute(file);

//2、安裝

Intent i = new Intent(Intent.ACTION_VIEW);

if(Build.VERSION.SDK_INT

i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

i.setDataAndType(Uri.fromFile(file),

"application/vnd.android.package-archive");

}else {

i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

String packageName = getApplication().getPackageName();

Uri contentUri = FileProvider.getUriForFile(MainActivity.this, packageName+ ".fileProvider", file);

i.setDataAndType(contentUri,"application/vnd.android.package-archive");

}

startActivity(i);

}

}

}

記得開啟讀寫SDCard權限。

native-lib.cpp

#include

#include

extern "C"{

//引入bspatch.c里的main方法

extern int main(int argc,char * argv[]);

}

extern "C"

JNIEXPORT void JNICALL

Java_com_example_zuo_bsdiff_MainActivity_bspatch(JNIEnv *env, jobject instance, jstring oldapk_,

jstring patch_, jstring output_) {

const char *oldapk = env->GetStringUTFChars(oldapk_, 0);

const char *patch = env->GetStringUTFChars(patch_, 0);

const char *output = env->GetStringUTFChars(output_, 0);

int argc = 4;

char *argv[4] ={"", const_cast(oldapk),const_cast(output),const_cast(patch)};

main(argc,argv);

env->ReleaseStringUTFChars(oldapk_, oldapk);

env->ReleaseStringUTFChars(patch_, patch);

env->ReleaseStringUTFChars(output_, output);

}

因為在android7.0以上調用安裝界面需要特殊處理:

在AndroidManifest.xml文件中添加provider,這里的provider介紹可以參考博客:android 7.0 因為file://引起的FileUriExposedException異常

android:authorities="com.example.zuo.bsdiff.fileProvider"

android:name="android.support.v4.content.FileProvider"

android:exported="false"

android:grantUriPermissions="true">

android:resource="@xml/file_paths"/>

新建一個file_paths.xml

四、打包

分別打一個1.0版本的apk包,在打一個2.0版本的apk包,然后使用./bsdiff app-1.apk app-2.apk patch生成個差分包,將這個差分包考到/sdcard下,安裝舊版本的apk后,更新就可以升級到2.0版本的apk

大致的效果圖如下:

增量更新效果圖

總結

以上是生活随笔為你收集整理的linux android sdk gengxinman,Android 实现增量更新的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。