Reproduced with
Zhouhuiah's Column http://blog.csdn.net/zhouhuiah/article/details/16939937
This article adds exception handling based on the above two blogs and packages the resulting so library with the native code.
1. Preparation Tools
(1) Bspatch Source (click to download), two different versions of an application. or directly download the tools and materials provided by the first blogger mentioned above. Click to open the link here The bread includes the Bsdiff source code and APK that we need to use.
(2) In addition, you need to download bzip2. Click to open link
2. Compiling environment
Linux, Windows can, but must have ndk,windows under the NDK version needs to be above R7, otherwise need to install Cygwin. Under Windows to build the NDK environment, please refer to: NDK configuration
3. Code implementation
(1) Create Native method class
Look at the code first:
[Java]View Plaincopy
- Public class patchclient{
- //define native method
- static private native int applypatchtooldapk (string oldapk_filepath, String Newapk_savepath, String Patchpath);
- public static void Loadlib () {
- System.loadlibrary ("patchdroid");
- }
- /**
- *
- * @param oldapkpath The path to the old apk file
- * @param newapkpath The path of the new APK file
- * @param the path of the Patchpath incremental package
- * @throws IOException
- */
- public static void Applypatch (String oldapkpath, String Newapkpath, String Patchpath) throws IOException {
- applypatchtooldapk (Oldapkpath, Newapkpath, Patchpath);
- }
- /**
- * Get the old apk file of this app according to the context, merge with the incremental package to generate the new version apk
- * @param context
- * @param newapkpath new apk file path
- * @param patchpath Incremental Package path
- * @throws IOException
- */
- public static void Applypatchtoown (context context, string Newapkpath, String Patchpath) throws ioexception{
- String old = Context.getapplicationinfo (). SourceDir;
- APPLYPATCHTOOLDAPK (old, Newapkpath, Patchpath);
- }
- }
The focus is on the third line of the code, and several other methods are described later. After compiling, the. class file is generated under the project's bin/classes, open cmd, cut to the directory, enter
[Plain]View Plaincopy
- Javah cn.sgwhp.PatchDroid (package name. Class name)
The header file Cn_sgwhp_patchdroid_patchclient.h is generated, the JNI folder is created at the root of the project, and the. h file that you just generated is cut past.
(2) Implement native method
Unzip the downloaded BZIP2 package and Bspatch source to the JNI directory, bspatch.c named cn_sgwhp_patchdroid_patchclient.c, Implementing JAVA_CN_SGWHP_PATCHDROID_ Patchclient_applypatchtooldapk method. Here we simply invoke the main method of the source code to implement:
[CPP]View Plaincopy
- #include "Cn_sgwhp_patchdroid_patchclient.h"
- #include "Bzlib_private.h"
- Jniexport jint jnicall java_cn_sgwhp_patchdroid_patchclient_applypatchtooldapk (jnienv *env,
- Jobject obj, jstring old, jstring new, jstring patch) {
- int argc=4;
- char * ARGV[ARGC];
- argv[0]="Bspatch";
- argv[1]= (char*) ((*env)->getstringutfchars (env,old, 0));
- argv[2]= (char*) ((*env)->getstringutfchars (env,new, 0));
- argv[3]= (char*) ((*env)->getstringutfchars (env,patch, 0));
- int Ret=applypatch (argc, argv, env); //The main method in the source code can be changed to Applypatch
- (*env)->releasestringutfchars (env,old,argv[1]);
- (*env)->releasestringutfchars (env,new,argv[2]);
- (*env)->releasestringutfchars (env,patch,argv[3]);
- return ret;
- }
(3) Exception handling
Only C in the source code err exception, Java is no way to output these exception information in the console, we will transform it, using jnienv Thrownew method to throw IOException. Add the Throwioexception method to the CN_SGWHP_PATCHDROID_PATCHCLIENT.C and remove the env parameter from the Java_cn_sgwhp_patchdroid_patchclient_ applypatchtooldapk Incoming Applypatch:
[CPP]View Plaincopy
- void Throwioexception (jnienv* env,const char* msg)
- {
- Find class type for the specified name
- Jclass cls= (*env)->findclass (env,"java/io/ioexception");
- (*env)->thrownew (env,cls,msg);
- (*env)->deletelocalref (ENV,CLS);
- }
- int Applypatch (int argc,char * argv[],jnienv* env)
- { ...}
Comment out all code in the Applypatch method that calls the Err method, and change it to:
[CPP]View Plaincopy
- Throwioexception (env, "Can not open the patch file");
- return 0
At this point, Applypatch and Applypatchtoown in the native method class declare the IOException to be thrown, preventing the program from exiting because of an exception.
(4) Compiling
Create the Android.mk file under the JNI directory and copy the following code:
[CPP]View Plaincopy
- Local_path:= $ (call My-dir)
- Include $ (clear_vars)
- # This is the target being built.
- local_module:= patchdroid
- # All of the source files that we'll compile.
- # exactly what C code is needed, not carefully studied
- local_src_files:= cn_sgwhp_patchdroid_patchclient.c \
- BZLIB.C \
- BLOCKSORT.C \
- COMPRESS.C \
- CRCTABLE.C \
- DECOMPRESS.C \
- HUFFMAN.C \
- RANDTABLE.C \
- BZIP2.C \
- Ifeq ($ (host_os), Windows)
- #NDK环境下
- Local_ldlibs: =-llog
- Else
- #完整源码环境下
- Local_shared_libraries: = Libutils
- endif
- Local_shared_libraries: = \
- Libandroid_runtime
- # No static libraries.
- Local_static_libraries: = \
- Libbz
- # Also need the JNI headers.
- Local_c_includes + = \
- $ (jni_h_include) external/bzip2
- # No Special Compiler flags.
- Local_cflags + =
- Include $ (build_shared_library)
Refresh the project the NDK will automatically compile for us.
4. Packing
Right-click the project, select Properties, select Android, tick the is Library, save the Clean project, and a jar package will be generated in the bin directory. When other projects need to be used, the jar package is imported and the Armeabi directory under the Libs directory is copied to the Libs directory of the new project.
5, something
For Applypatchtoown (context context, string Newapkpath, String Patchpath) method: After the program is installed, the APK file will exist in the/data/app directory, the name is "package name-number." APK ", where" numbers "are generally 1 or 2, it is unclear what the rules are. But it doesn't matter, we can get the current version of the APK absolute path through ApplicationInfo SourceDir, so as long as the incremental package download to the SD card can be synthesized new version of the APK. Remember to add read and write permissions to the external storage device.
Incremental upgrade (Save traffic update) for Android client implementation