The Dex files in the apk file in Android are repackaged by Java-compiled. class files, which, of course, use their own protocols to do some data processing before packaging, such as optimizing function tables and variable tables. In Java programs, you use ClassLoader to load the. class files generated by these compilations, but in the Android program they are loaded by dexclassloader. Here we can go through Dexclassloader in program a dynamically loads the class in program B, and calls the methods in the B program.
1. First build a common Android project in which a class called plugin is defined, and a simple method is implemented in the class, as follows:
<span style= "FONT-SIZE:14PX;" >public class Pluginclass {private static String TAG = PluginClass.class.getSimpleName ();p ublic Pluginclass () {LOG.I ( TAG, "initialized");} public void Invoke (String s) {log.i (TAG, s);}} </span>
2. Run the Android project into the Android device
3. Re-establish an Android project that defines a class called host that implements Dexclassloader dynamically loading the plugin class in the first project as follows:
<span style= "FONT-SIZE:14PX;" >public class Hostclass {private static String TAG = HostClass.class.getSimpleName ();p rivate Context mcontext = Null;pu Blic Hostclass (Context contect) {mcontext = contect;} public void Usedexclassloader () {Intent Intent = new Intent (); Intent.setpackage ("Com.example.plugin"); Packagemanager pm = Mcontext.getpackagemanager (); final list<resolveinfo> plugins = pm.queryintentactivities ( intent,0); if (plugins.size () <= 0) {log.i (TAG, "Resolve info size is:" + plugins.size ()); return;} ResolveInfo ResolveInfo = plugins.get (0); Activityinfo activityinfo = Resolveinfo.activityinfo; String div = system.getproperty ("Path.separator"); String PackageName = activityinfo.packagename; String Dexpath = activityinfo.applicationinfo.sourcedir;//The path of the APK or jar where the target class is located, and class loader will load the target class file with this path string Dexoutputdir = Mcontext.getapplicationinfo (). datadir;//since the Dex file is included in the APK or jar file, the Dex file needs to be extracted before the class is loaded. Dexoutputdir for decompression path string libPath = ActivityInfo.applicationInfo.nativeLibrarydir;//the target class may use the C or C + + library file to store the path log.i (TAG, "div:" + div + "" + "PackageName:" + PackageName + "" + "Dexpath:" + Dexpath + "" + "Dexoutputdir:" + Dexoutputdir + "" + "LibPath:" + libPath);D exclassloader dcloader = new Dexclassloader (DEXPA Th,dexoutputdir,libpath,this.getclass (). getClassLoader ()); try {class<?> clazz = Dcloader.loadclass ( PackageName + ". Pluginclass "); Object obj = Clazz.newinstance (); class[] param = new class[1];p aram[0] = String.class; Method action = Clazz.getmethod ("Invoke", Param), Action.invoke (obj, "Test this function"); catch (ClassNotFoundException e) {log.i (tag, "ClassNotFoundException"),} catch (Instantiationexception e) {log.i (tag, " Instantiationexception ");} catch (Illegalaccessexception e) {log.i (tag, "Illegalaccessexception"),} catch (Nosuchmethodexception e) {log.i (tag, " Nosuchmethodexception ");} catch (IllegalArgumentException e) {log.i (TAG, "illegalargumentexception");} catch (InvocationTargetException e) { LOG.I (TAG, "invocationtargetexception");}}} </span>4. After running the second project, check log to find that host loaded the Pluginclass class through Dexclassloader and successfully called the method in plugin
<span style= "FONT-SIZE:14PX;" >i/hostclass (8341): div:: PackageName:com.example.plugin dexpath:/data/app/com.example.plugin-1.apk DEXOUTPUTDI R:/data/data/com.example.host LIBPATH:/DATA/APP-LIB/COM.EXAMPLE.PLUGIN-1D/DALVIKVM (8341): DexOpt:---BEGIN ' com.example.plugin-1.apk ' (bootstrap=0)---D/DALVIKVM (8341): dexopt:---END ' com.example.plugin-1.apk ' (success)---D /DALVIKVM (8341): DEX Prep '/data/app/com.example.plugin-1.apk ': Unzip in 39ms, rewrite 723msi/pluginclass (8341): Initia Lizedi/pluginclass (8341): Test this FUNCTIOND/LIBEGL (8341): Loaded/system/lib/egl/libegl_mali.sod/libegl (8341): Lo Aded/system/lib/egl/libglesv1_cm_mali.sod/libegl (8341): Loaded/system/lib/egl/libglesv2_mali.sod/openglrenderer (8341): Enabling Debug mode 0i/hostclass (8341): div:: PackageName:com.example.plugin dexpath:/data/app/com.example.p lugin-1.apk Dexoutputdir:/data/data/com.example.host Libpath:/data/app-lib/com.example.plugin-1i/pluginclass ( 8341): initializedi/pLuginclass (8341): Test this function</span>
Android uses Dexclassloader to run other apk methods