In Android development, there are a lot of times when you need to use dynamic loading, today to learn how to dynamically load the installed APK in Android.
First, we need to create a new Android project to be loaded, and give him a name called: plugproj
Create a new class Dynamic in Plugproj, in which we create new methods, and so on, we will load these methods separately when the project is installed and not installed, Dynamic.java as follows:
Package Com.example.plugproj;import Android.app.activity;import Android.widget.toast;public class Dynamic {Activity mactivity = null;public void init (activity activity) {//TODO auto-generated method stubmactivity = activity;} public void ShowDialog () {//TODO auto-generated method Stubtoast.maketext (mactivity, "Show dialog Test Gaga", Toast.lengt H_long). Show ();} public void ShowWindow () {//TODO auto-generated method Stubtoast.maketext (mactivity, "show window Test Gaga", Toast.lengt H_long). Show ();} public int Addmethod (int a, int b) {//TODO auto-generated method Stubreturn A + b;}}
As you can see in the Init method, we assign a value to its mactivity, which is to get the context object so that the toast can be executed.
It is also important to note that we need to configure an action for the start activity of the Plugproj project so that we can load the corresponding package with this action, as follows:
<activity android:name= "com.example.plugproj.MainActivity" android:label= "@string/app_name" > <intent-filter> <action android:name= "Android.intent.action.MAIN"/> <category Android:name= "Android.intent.category.LAUNCHER"/> </intent-filter> <intent-filter> <action android:name= "Com.haha.android.plugin"/> </intent-filter> </activity>
Install the Plugproj project.
Next look at another main project, the project that loads Plugproj, the main code is as follows:
Create an intent to find the specified apk Intent Intent = new Intent ("Com.haha.android.plugin", null); Get Package Manager Packagemanager PM = Getpackagemanager (); list<resolveinfo> resolveinfoes = pm.queryintentactivities (Intent, 0); Gets the information for the specified activity activityinfo actinfo = resolveinfoes.get (0). Activityinfo; Get the package name String pacagename = actinfo.packagename; Get the directory of the APK or the directory of the jar String Apkpath = ActInfo.applicationInfo.sourceDir; Dex Unzip the directory, note that this directory with the host program, Android only allows the program to read write itself//directory under the file String Dexoutputdir = Getapplicationinfo (). DataDir; Directory of native code String LibPath = ActInfo.applicationInfo.nativeLibraryDir; Create the class loader and load Dex into the virtual machine dexclassloader Calssloader = new Dexclassloader (Apkpath, Dexoutputdir, LibPath, This.getclass () . getClassLoader ()); try {clazz = Calssloader.loadclass (pacagename+ "). Dynamic "); obj = Clazz.newinstance (); Method Initmethod = Clazz.getdeclaredmethod ("init", Activity.class); Initmethod.invoke (obj,mainactivity.this);} catch (ClassnotfouNdexception e) {e.printstacktrace ()} catch (Instantiationexception e) {//TODO auto-generated catch Blocke.printstacktrace ();} catch (Illegalaccessexception e) {//TODO auto-generated catch Blocke.printstacktrace ();} catch ( IllegalArgumentException e) {//TODO auto-generated catch Blocke.printstacktrace ();} catch (InvocationTargetException E {//TODO auto-generated catch Blocke.printstacktrace ();} catch (Nosuchmethodexception e) {//TODO auto-generated catch Blocke.printstacktrace ();}
Next is the OnClick event that executes the above three methods:
@Overridepublic void OnClick (View arg0) {//TODO auto-generated method stubtry {switch (Arg0.getid ()) {case R.ID.I D_dialog:method Dialogmethod = Clazz.getdeclaredmethod ("ShowDialog", null);d ialogmethod.invoke (obj, null); LOG.D ("Tag", "Show dialog runs ..."); break;case r.id.id_window:method Windowmethod = Clazz.getdeclaredmethod (" ShowWindow ", null); Windowmethod.invoke (Obj,null); LOG.D ("Tag", "show window Runs ..."); Break;case r.id.id_plus:class[] param = new class[2]; Param[0] = Integer.type; PARAM[1] = Integer.type; method = Clazz.getdeclaredmethod ("Addmethod", param); int result = (Integer) method.invoke (obj, 22,33); Toast.maketext (mainactivity.this, "result is:" +result,toast.length_short). Show (); LOG.D ("Tag", "Add Runs ..."), Break;default:toast.maketext (Mainactivity.this, "No property id", Toast.length_long). Show ();}} catch (Nosuchmethodexception e) {e.printstacktrace ();} catch (Illegalaccessexception e) {e.printstacktrace ();} catch ( Illegalargumentexception e) {e.printstacktrace ();} catch (InvocationTargetException e) {e.printstacktrace ()}}
This implements the method of loading the installed apk.
Next look at how the load has been packaged into a jar file:
First, you need to export the plugproj as a jar file, We export here as Plugproj.jar, note that this time the jar file on the Android phone is not directly loaded, we need to convert him to Dex file, how to convert it, there is a DX tool under the SDK, you can use it to implement, Copy the Plugproj.jar to the directory that owns the DX file, typically in Platform_tool, sometimes under the Build_tools folder, and then enter the file with a command:
Execute the following command:
DX--dex--output optimized jar with no optimized jar
An optimized jar file is generated, which is what our Android phone can load directly. Copy the jar file to the directory specified by your phone:
Here's the key code:
String Path = "/storage/sdcard0/183/mydynamic_help.jar";d Expath = Getdir ("dex", Context.mode_private). GetAbsolutePath ();d exclassloader = new Dexclassloader (path, Dexpath, NULL, getClassLoader ()); try {clazz = Dexclassloader.loadclass ("com.example.plugproj.Dynamic"); try {obj = clazz.newinstance (); method = Clazz.getdeclaredmethod ("init", Activity.class); Method.invoke (obj, mainactivity.this); LOG.D ("Tag", "Dynamic init runs ..."); catch (Instantiationexception E1) {e1.printstacktrace ();} catch (Illegalaccessexception E1) {e1.printstacktrace ();} catch (Nosuchmethodexception e) {e.printstacktrace ();} catch (IllegalArgumentException e) {e.printstacktrace ();} catch (InvocationTargetException e) {E.printstacktrace ();}} catch (ClassNotFoundException e) {e.printstacktrace ();}
To bind the OnClick event to a button:
public void OnClick (View arg0) {//TODO auto-generated method stubtry {switch (Arg0.getid ()) {case R.id.id_dialog:method M Ethod = Clazz.getdeclaredmethod ("ShowDialog", null); Method.invoke (obj, null); LOG.D ("Tag", "Show dialog runs ..."); Break;case R.id.id_window:method = Clazz.getdeclaredmethod ("ShowWindow", null); Method.invoke (obj, null); LOG.D ("Tag", "show window Runs ..."), Break;case r.id.id_plus:<span style= "White-space:pre" ></span>class[ ]param = new Class[2];p aram[0] = integer.type;param[1] = Integer.type; method = Clazz.getdeclaredmethod ("Addmethod", param); int result = (Integer) method.invoke (obj,23,25); <span style= " White-space:pre "></span>toast.maketext (mainactivity.this," result is: "+result,toast.length_short). Show ( ); LOG.D ("Tag", "Add Runs ..."), Break;<span style= "White-space:pre" ></span>default:toast.maketext ( Mainactivity.this, "No property id", Toast.length_long). Show ();}} catch (Nosuchmethodexception e) {e.printstacktrace ();} catch (IllegalaccesseXception e) {e.printstacktrace (),} catch (IllegalArgumentException e) {e.printstacktrace ();} catch ( InvocationTargetException e) {e.printstacktrace ();}}
Finally, remember to add permissions to read and write to the SD card.
<uses-permission android:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/>
SOURCE download
Dynamically loading Jars
Android dynamically loading the installed APK method