Codeegg’s 785th tweet
Size girls see the world
Introduction to Android incremental updates
To be clear, Android incremental updates and hot fixes are different technical concepts.
Hot fixes are generally used when a Bug needs to be fixed in a released app. Developers modify the code and release patches so that the app can be updated without the need for a re-installation. Mainstream solutions have a Tinker (https://github.com/Tencent/tinker), AndFix (https://github.com/alibaba/AndFix), etc.
The purpose of incremental update is to reduce the volume of the package that needs to be downloaded to update the APP. For example, the volume of APK package is several hundred meters, but sometimes the update only needs to download more than ten meters of the installation package to complete the update.
The principle of incremental update is simply to find the differences between the new version and the old version through the binary algorithm, and extract the differences to generate the so-called patch package (differential subcontract). When the mobile terminal checks the update, it only needs to apply to the server to download the corresponding patch package, and then merge the difference package with its old version APK to generate the latest version APK. The final installation of the apK generated by the merge completes the version update.
The realization of the function is mainly with the help of third party difference tools, equivalent to doing records, convenient later recall.
Demonstration of incremental update process
There are two main processes for incremental updates. First, the background compares the latest APK (V1.0.1) with the previous version (v1.0.0) and generates subcontracting. The second step is to download the corresponding subpackage on the mobile terminal and merge it locally to generate the complete latest APK and guide the user to install it.
For difference and merge apk package, need bsdiff (https://www.pokorra.de/coding/bsdiff.html) tools to achieve
Download bsdiff_win_exe.zip and unzip it locally
Where bsdiff.exe is the tool used by Window to generate subcontracting, and bspatch is the tool used to synthesize subcontracting
2.1 Generation of subcontracting
First of all, type an old APK (v1.0.0.apk) and a new APk (v1.0.1.apk) respectively and store them in the directory that you extracted previously.
Then open the Windows command line tool, switch to the directory, and type the command bsdiff v1.0.0.apk v1.0.1.apk patch.patch
You can see the generated subpackage patch.patch in the directory
2.2 Composite subcontracting
Keep in the current directory and type bspatch v1.0.0.apk new.apk patch.patch
You will see the complete installation package new.apk synthesized in the current directory
The generated new.apk is exactly the same as v1.0.1.apk, just install it.
Incremental updates for Android applications
The above procedure is to demonstrate the process and is now applied to the Android side. During the incremental update process, Android mobile is only responsible for downloading and merging subpackages and guiding users to install them. Therefore, assume that the corresponding subcontracting has been downloaded. There are three main steps: the first is to obtain its own old APK path; The second is to integrate the difference tool into Android. The third is to call the method to merge the subcontracting and guide the user to install.
3.1 Obtaining the Installed Old APK Path
// Get the current running APK path
String oldApk = getApplicationInfo().sourceDir;
Copy the code
Copy the code
3.2 Integrate the differential merge function into Android
Bsdiff open source tool source for. C file, that is, the Android side needs to configure JNI (following is based on CMake).
To facilitate integration, required functions have been packaged into the SO package. You can import the SO package directly. Skip this step. Baidu network backup link (https://pan.baidu.com/share/init?surl=yBx3u5eAD7p30qPCjtfm2A) (8 ia7 extraction code:)
Bsdiff (https://www.pokorra.de/coding/bsdiff.html) source dependent bszip (http://www.bzip.org/downloads.html).
3.2.1 Import required Source files
-
Unzip the bsdiff-4.3.tar.gz file and copy the bspatch.c file to your Android CPP directory
-
Unzip the bzip2-1.0.6.tar.gz file and copy the required source files to the Android CPP /bzip directory as shown
-
Modify the contents of the bspatch.c file
(1) Modify the import declaration of bzlib.h: open the bspatch. C file and modify the header file
2) Find the main method and rename it execute_patch
3.2.2 Configuring the CMakLists. TXT file
Cmake_minimum_required (VERSION 3.4.1 track)
# find the path of the specified pattern in the file system, such as /* file matching the root directory (note the path)
file(GLOB bzip_source ${CMAKE_SOURCE_DIR}/bzip/*.c)
# set up local dynamic library compilation to generate dynamic library
add_library(
# module name
native-lib
# Dynamic library/sharing ok
SHARED
# the source file
native-lib.cpp
Configure the corresponding file references
bspatch.c
${bzip_source}
)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
Copy the code
Copy the code
3.2.3 Adding calling methods to native-lib. CPP
extern "C" {
extern int execute_patch(int argc, char *argv[]);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_utilities_BsPatchUtil_patch(JNIEnv *env, jobject instance, jstring oldApk_,
jstring patch_, jstring output_){
// Convert a Java string to a char pointer
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)};
execute_patch(4, argv);
// Release the corresponding pointer gc
env->ReleaseStringUTFChars(oldApk_, oldApk);
env->ReleaseStringUTFChars(patch_, patch);
env->ReleaseStringUTFChars(output_, output);
}
Copy the code
Copy the code
Note: The Java_com_example_myapplication_utilities_BsPatchUtil_patch method name needs to be changed based on the actual definition
3.3 Defining methods: The Java layer uses composition functionality
Define a BsPatchUtil class and call c code :(this method name should correspond to the Java_com_example_myapplication_utilities_BsPatchUtil_patch method name mentioned above)
public class BsPatchUtil {
static {
System.loadLibrary("native-lib");
}
/ * *
* @param oldApkPath Old APK file path
* @param newApkPath New APK file path
* @param patchPath Storage path of the generated subpackage
* /
public static native void patch(String oldApkPath, String newApkPath, String patchPath);
}
Copy the code
Copy the code
3.4 Composite subcontracting
// The path to the installed old APK
val oldApk = applicationInfo.sourceDir
// Subcontract path
val patch = ...
// Store path of the synthesized new APK
val output = ...
// Synthesize apK package
BsPatchUtil.patch(oldApk, patch, output)
Copy the code
Copy the code
Synthetic subcontracting needs to run in child threads to prevent blocking the main thread. Finally, boot the user to install the newly generated APK.
Related articles:
-
How did I manage to open the complex App for 1s?
-
I’ve doubled my assets! You still don’t know what blockchain is?
-
Good developers need these 10 steps!
Question of the day:
Why do people use incremental updates?
Exclusive upgrade community: I Finally Figured it out