Introduction of Loader
"Class loader" (ClassLoader), as the name suggests, is used to dynamically load class files. The standard Java SDK has a ClassLoader class that enables you to load the required class files, provided that
ClassLoader class initialization must be made to the path of the class file.
The difference between the class file referenced by the Import keyword and the classloader dynamic load class:
The import reference class has two characteristics: 1, which must exist locally, and when the program runs the class, the inner class loader automatically loads the class.
2, compile-time must be in the field, otherwise the compilation process will not be able to find the reference file can not compile correctly.
The characteristics of ClassLoader are precisely the opposite of import, and are more free and flexible.
Each ClassLoader must have a parent ClassLoader, when the class file is loaded, the child ClassLoader first requests its parent ClassLoader to load the file, and only if the file is not found by its parent ClassLoader The ClassLoader will inherit the class. This is a security mechanism. For Android, the final apk file contains the Dex type of file, Dex file is the class file repackaging, packaging rules are not simply compressed, but the class file inside the various function tables, variable table optimization, resulting in a new file, that is, Dex file. So loading this special class file requires a special ClassLoader dexclassloader.
Ii. the practical application of the Dexclassloader method
Suppose there are two apk, the first is called host, and the second is called plugin. The first class in the plugin is plugin, and a addition function is defined in the class.
Package com.david.plugin;
Import Android.util.Log;
public class Plugin {
private static final String tag=plugin.class.getsimplename ();
Public Plugin () {
log.i (TAG, ' pluginclass is initialized ');
}
public int addition (int a,int b) {return
a+b;
}
}
In the plugin apk androidmanifest file, the activity must declare an action.
<activity
android:name= "com.david.plugin.MainActivity"
android:label= "@string/app_name" >
<intent-filter>
<action android:name= "com.david.plugin.client"/>
<action android:name= " Android.intent.action.MAIN " />
<category android:name=" Android.intent.category.LAUNCHER " >
</intent-filter>
</activity>
See more highlights of this column: http://www.bianceng.cnhttp://www.bianceng.cn/OS/extra/
The
Loads the plugin.apk into the Android device. The code for the main activity call in HOST.APK is as follows:
Package com.david.host;
Import java.lang.reflect.InvocationTargetException;
Import Java.lang.reflect.Method;
Import java.util.List;
Import Dalvik.system.DexClassLoader;
Import android.support.v7.app.ActionBarActivity;
Import Android.annotation.SuppressLint;
Import android.content.Intent;
Import Android.content.pm.ActivityInfo;
Import Android.content.pm.PackageManager;
Import Android.content.pm.ResolveInfo;
Import Android.os.Bundle;
Import Android.view.View;
Import Android.view.View.OnClickListener;
Import Android.widget.Button; public class Mainactivity extends actionbaractivity implements onclicklistener{private static final String Plugi
N_package = "Com.david.plugin.client";
Private Packagemanager pm;
Private Resolveinfo Resolveinfo;
Private Button Btn_classloader;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main); usEdexclassloader ();
Btn_classloader= (Button) Findviewbyid (R.id.btn_classloader);
Btn_classloader.setonclicklistener (this); @SuppressLint ("Newapi") public void Usedexclassloader () {Intent classintent = new Intent (PLUGIN_PA
Ckage, NULL);
PM = Getpackagemanager ();
List<resolveinfo> activities = pm.queryintentactivities (classintent, 0);
Resolveinfo = activities.get (0);
Activityinfo activityinfo = Resolveinfo.activityinfo;
String div = system.getproperty ("Path.separator");
String PackageName = activityinfo.packagename;
String SourceDir = ActivityInfo.applicationInfo.sourceDir;
System.out.println (SourceDir);
String OutDir = Getapplicationinfo (). DataDir;
System.out.println (OutDir);
String librarydir = ActivityInfo.applicationInfo.nativeLibraryDir;
System.out.println (Librarydir); Dexclassloader dexcl = new Dexclassloader (SourceDir, OUTdir, Librarydir, This.getclass (). getClassLoader ()); try {class<?> loadclass = Dexcl.loadclass (packagename+).
Plugin ");
Object instance = Loadclass.newinstance ();
class[] params = new class[2];
Params[0]=integer.type;
Params[1]=integer.type;
Method method = Loadclass.getmethod ("addition", params);
Integer result = (integer) method.invoke (instance, 12,32);
SYSTEM.OUT.PRINTLN (result);
catch (ClassNotFoundException e) {e.printstacktrace ();
catch (Instantiationexception e) {e.printstacktrace ();
catch (Illegalaccessexception e) {e.printstacktrace ();
catch (Nosuchmethodexception e) {e.printstacktrace ();
catch (IllegalArgumentException e) {e.printstacktrace ();
catch (InvocationTargetException e) {//TODO auto-generated catch block E.printstacktrace ();
@Override public void OnClick (View v) {usedexclassloader (); }
}
The results obtained after running are:
The class loader still uses more in the application and can design a "plug-in" architecture based on it.