Android增量更新

首先增量更新應該瞭解個概念: 增量更新:在版本較近的apk升級的時候,根據兩個apk之間的差別(生成差別包),合成新的安裝包,在應用內部進行升級的一種操做(須要從新安裝apk文件)。 熱更新:在發佈的版本有BUG的時候,動態加載dex文件,在不影響apk的狀況下進行修復BUG(不須要從新安裝apk文件)。java

因此從本質上增量更新和熱更新是不一樣的!這個概念要明確。。。android

本文知識點:

  • android 增量更新的一些工具
  • android 增量更新的配置(JNI的配置)
  • android 增量更新的開發
  • android 遇到的一些問題
  • demo地址的分享

1. 增量更新的一些工具

所謂工欲善其事,必先利其器。因此工具是很重要的!這裏先和你們介紹一下相應的工具!!!c++

  • 1.2 bzip2-1.0.6 用於補充bsdiff中c的缺失代碼
  • 1.3 bsdiff-v4.3-win-x64 用於生成相應的差別包

鑑於你們的找着費勁,因此呢~因此呢~我也沒準備!哈哈!!!開玩笑,這裏是我百度網盤的地址(增量更新工具 提取碼爲r1ws),若是失效的話!及時聯繫我哦!git

2. 增量更新的配置(JNI的配置)

其實每次配置jni的環境我都頭疼,可是爲了工做也是沒辦法。後來我發現一個事情,假如以前項目沒有ndk那麼怎麼能快速集成呢?這裏我每次都是新建一個ndk項目而後各類copy就行了!!!程序員

2.1 導入bspatch.c文件(這個是在bsdiff-4.3中的,夠體貼吧!!!)

其實在當你導入這個文件的時候,你會發現。媽的一堆紅。。。這是在逗我嗎?別急,以後就行了!!!github

2.2 導入bspatch.c文件所須要的文件

記得當初讓大家下的bzip2吧?其實卻得就是這個裏面得一些東西!!!其實你把倆面的東西全都搞過來是能夠的,可是做爲一個有逼格的程序員,這怎麼可能呢?那麼須要導入那些文件呢?看看下面這段代碼(在bzip中有一個Makefile文件中的代碼):bash

OBJS= blocksort.o  \
      huffman.o    \
      crctable.o   \
      randtable.o  \
      compress.o   \
      decompress.o \
      bzlib.o
複製代碼

對須要的就是這些文件!我把我導入的文件的示意圖放上了,按照名稱直接導入就行了!服務器

這裏面有一些坑須要踩:架構

  1. 在導入bzlib.h文件的時候,android studio3.+和以前的有區別(看那個不報錯用哪一個吧):
//#include <bzlib.h>
//新版本只有這樣能導入
#include "bzip/bzlib.h"
複製代碼
  1. 在bspatch.c文件中有一個main方法,最好把這個名稱改爲別的,防止其它c代碼也使用這個main方法,形成出錯!

2.3 配置jni環境

這個我感受是最繁瑣的,其實配置這些真的好煩,,,行了不發牢騷了!!!app

2.3.1 建立生成bsPath的方法!

其實這個就是一個jni的方法,注意這別忘了加載lib哦!建立完的話native_lib應該是這樣的!!!

#include <jni.h>
#include <string>

//這個主要是爲了導入其中的方法
extern "C" {
extern int p_main(int argc, char *argv[]);
}
extern "C"
JNIEXPORT void JNICALL Java_com_angle_netupdatademo_MainActivity_bsPath(JNIEnv *env, jobject instance, jstring oldApk_, jstring patch_, jstring output_) {

    //將java字符串轉換成char指針
    const char *oldApk = env->GetStringUTFChars(oldApk_, 0);
    const char *patch = env->GetStringUTFChars(patch_, 0);
    const char *output = env->GetStringUTFChars(output_, 0);

    // 釋放相應的指針gc
    env->ReleaseStringUTFChars(oldApk_, oldApk);
    env->ReleaseStringUTFChars(patch_, patch);
    env->ReleaseStringUTFChars(output_, output);
}
複製代碼

這裏面的內容咱們一會在盤他!!!

2.3.2 配置CMakeLists.txt文件

其實關於這塊我以爲有必要系統的學習一下,因此這裏咱們就不作太多介紹了,我註解寫的很詳細的!!!

cmake_minimum_required(VERSION 3.4.1)

# 查找文件系統中指定模式的路徑,如/* 匹配根目錄的文件(注意路徑)
file(GLOB bzip_source ${CMAKE_SOURCE_DIR}/bzip/*.c)

# 設置本地動態庫 編譯生成動態庫
add_library(
        #模塊名
        native-lib
        # 動態庫/分享能夠
        SHARED

        #源文件
        native-lib.cpp

        #配置相應的文件引用
        bspatch.c
        #這個至關與別名引用,上面設置了一個別名
        ${bzip_source}
)

#系統庫,日誌輸出log
find_library(
        log-lib

        log)

#須要連接或者編譯的庫
target_link_libraries(
        native-lib

        ${log-lib})
複製代碼

基本上就是這些配置了!!!

2.3.3 app的build.gradle配置相應的內容

這裏其實就是在c++的demo中添加了相應的cpu架構的兼容

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.angle.netupdatademo"
        minSdkVersion 14
        targetSdkVersion 28
        versionCode 1
        versionName "2.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
                //兼容cpi架構
                abiFilters 'armeabi-v7a'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
}
複製代碼

這裏也沒有什麼太多好說的,關於這些建議看看jni配置的一些文章!


以上全部的配置就結束了!!! 是否是很煩,沒事,立刻就看到日出了!!!

3. 增量更新的開發

其實通常的增量更新都是在splash頁面中動態從服務器下載patch文件,放在某個文件夾下,而後經過以前安裝apk的路徑進行生成新包,最後安裝。基本上就是這個流程!

因此這裏須要解決的一些內容:

  • pathc文件的生成
  • old.apk安裝的路徑的獲取
  • 怎麼生成新的安裝包

分解處任務就很好作了!

3.1 patch文件的生成

解壓bsdiff-v4.3-win以後會有兩個文件,直接把兩個android安裝包放進去以後,經過命令 bsdiff old.apk new.apk patch就能夠生成相應的patch文件了!

3.2 old.apk安裝路徑的獲取

其實這個很簡單,一行代碼就能搞定

String oldApk = getApplicationInfo().sourceDir;
複製代碼

3.3 怎麼生成新的apk文件

這裏就要用到咱們以前沒有盤的那個jni方法了!

#include <jni.h>
#include <string>

//這個主要是爲了導入其中的方法
extern "C" {
extern int p_main(int argc, char *argv[]);
}
extern "C"
JNIEXPORT void JNICALL Java_com_angle_netupdatademo_MainActivity_bsPath(JNIEnv *env, jobject instance, jstring oldApk_, jstring patch_, jstring output_) {

    //將java字符串轉換成char指針
    const char *oldApk = env->GetStringUTFChars(oldApk_, 0);
    const char *patch = env->GetStringUTFChars(patch_, 0);
    const char *output = env->GetStringUTFChars(output_, 0);

    //bspatch ,oldfile ,newfile ,patchfile
    char *argv[] = {"", const_cast<char *>(oldApk), const_cast<char *>(output), const_cast<char *>(patch)};
    p_main(4, argv);

    // 釋放相應的指針gc
    env->ReleaseStringUTFChars(oldApk_, oldApk);
    env->ReleaseStringUTFChars(patch_, patch);
    env->ReleaseStringUTFChars(output_, output);
}
複製代碼

看中間增長的那段代碼,這個p_main就是以前讓你改的那個main方法,須要四個參數,而後強轉。這裏面實際上是c的一些知識,我也不是很明白。可是代碼很好理解!

那麼接下來,就直接調用這個發方法生成一個相應的apk就能夠了!!!

4. 遇到的一些問題

  • 若是版本跨度太大的話,能夠直接更新相應的apk安裝包。不須要差分包了!很好理解,版本跨度過大的狀況,差分包和新包沒有什麼區別,不須要作差分了!

5. Demo地址

Demo地址

使用方法,生成一個apk(老的),而後增長內容,在生成一個apk(新的)。生成拆分包!而後把這兩個都放在sd卡的根目錄安裝老的apk,而後點擊更新!!!

相關文章
相關標籤/搜索