Overview
In the face of frequent changes to the app business logic, if every change is made to an app that upgrades the app's user experience, then the app's modular upgrade (here, unlike the incremental upgrade) is a good solution, Let the user change the business logic in the app without feeling completely. To implement this modular upgrade, the dynamic loading of bytecode (Jar/dex) is the theoretical basis for achieving this requirement.
android System load byte code
Android virtual machines (Dalvik VMs) do not recognize bytecode in normal jar packages, so you need to byte-code conversion tool converting the jar to all bytecode in the Dex,jar package will be entered into classes.dex, so that the bytecode can be identified by the Dalvik virtual machine.
Example Explanation
Source Download , need to prepare two works, an Android project (Androidpractice), to load bytecode in Android engineering. Ning outside a common Java project (dexmodule), look at the engineering structure below. It is important to note that the Idynamicload interface is required in both projects, and the package name is the same.
650) this.width=650; "class=" Size-full wp-image-685 "src=" http://vjson.com/wordpress/wp-content/uploads/2015/02/% E5%ad%97%e8%8a%82%e7%a0%81%e5%8a%a0%e8%bd%bd%e5%b7%a5%e7%a8%8b%e7%bb%93%e6%9e%84.png "alt=" bytecode loading engineering structure "width=" 400 "Height=" 608 "style=" Border:0px;margin:0px;padding:0px;vertical-align:baseline;height:auto;/>
Bytecode loading engineering structure
Dexmodule Engineering Explanation
Dexmodule this project only two classes, one is the interface idynamicload, this interface is the article began to mention the module upgrade key, only need to pre-contract the interface, the interface is published to the caller, the specific implementation of the caller is completely transparent, This can be done at random to change the implementation of the interface, Ning one is the implementation of the interface class Dynamicload. The implementation is very simple to return a string.
Package Com.vjson.module;public interface Idynamicload {public String dexload ();}
<span style= "Font-weight:normal;" >package Com.vjson.module;public class Dynamicload implements Idynamicload {@Override public String dexload () { Return "Dexload practice"; }}</span>
Export Jar Package
When exporting the jar package, it is important to note that do not export idynamicload This interface file, because the Android project already has an interface file, otherwise loading bytecode will cause bytecode conflict.
650) this.width=650; "class=" Size-full wp-image-691 "src=" http://vjson.com/wordpress/wp-content/uploads/2015/02/% E5%af%bc%e5%87%bajar%e5%8c%85.png "alt=" Export jar Package "width=" "height=" 609 "style=" border:0px;margin:0px;padding:0px; Vertical-align:baseline;height:auto; "/>
Export JAR Package
byte-code conversion
Using the bytecode conversion tool mentioned earlier, convert the jar to Dex known to the Dalvik VM. d2j-jar2dex.sh The-o parameter of this command specifies the output file.
D2j-jar2dex.sh-o Module.jar Dynamicload.jar
The resulting module.jar is then placed inside the sdcard of the phone.
ADB push module.jar/mnt/sdcard/
Load Dex
Loading bytecode requires the Dexclassloader class, which is responsible for extracting (a process of extracting) Classes.dex from the jar package and loading the bytecode into memory, then loading the required classes through the LoadClass method, looking at the detailed code below, Note the highlighted line.
package com.vjson.practice;import java.io.file;import android.annotation.targetapi;import android.app.activity;import android.os.build;import android.os.bundle;import Android.os.environment;import android.view.view;import android.view.view.onclicklistener;import android.widget.Button;import android.widget.Toast;import com.vjson.dynamicload.R;import Com.vjson.module.idynamicload;import dalvik.system.dexclassloader;public class mainactivity extends Activity { private Button mBtn; private IDynamicLoad mDynamicLoad; @TargetApi (build.version_codes. Ice_cream_sandwich) public static final idynamicload loadbytecode () { file jarfile = new file ( Environment.getexternalstoragedirectory (). toString () + file.separator + "Module.jar"); file Optmizedpath = baseapplication.sinstance.getdir ("Dex", mode_private); dexclassloader loader = new dexclassloader (JarFile.getAbsolutePath (), Optmizedpath.getabsolutepath (), null, baseapplication.sinstance.getclassloader ()); idynamicload dynaicload = null; try { Class<?> clazz = loader.loadclass ("Com.vjson.module.DynamicLoad"); dynaicload = (Idynamicload) clazz.newinstance (); } catch (classnotfoundexception e) { e.printstacktrace (); } catch ( Instantiationexception e) { E.printstacktrace (); } catch (IllegalAccessException e) { e.printstacktrace (); } return dynaicload; } @Override protected Void oncreate (bundle savedinstancestate) { Super.oncreate (savedinstancestate); &nbsP; setcontentview (R.layout.activity_main); mdynamicload = loadbytecode (); mBtn = (Button) findviewbyid (R.ID.BTN); Mbtn.setonclicklistener (New onclicklistener () { @Override Public void onclick (VIEW&NBSP;V) { string str = mdynamicload.dexload (); toast.maketext ( Getapplicationcontext (), str, toast.length_short). Show (); } }); }}
Note the code of 26 lines, through the context of the Getdir ("Dex", Mode_private) method gets the application's private directory, which is due to security reasons starting from Android4.1.2, preventing Code injection attacks , the bytes must be stacked into a private directory under the data/data/application package name/. The Classes.dex from the jar package is placed under this directory.
Summary
This article mainly introduces, the Android bytecode loading technology, for the next article Android Modular upgrade provides a theoretical basis, in fact, the most important thing is to define the interface, through the interface call and the implementation end of the communication. The integrity validation and security validation of the jar package will be explained in the modular upgrade.
Android Dynamic load byte code