編輯:Android開發教程
一、裝載器簡介
“類裝載器”(ClassLoader),顧名思義,就是用來動態裝載class文件的。標准的Java SDK中有個ClassLoader類,借助此類可以裝載需要的class文件,前提是
ClassLoader類初始化必須制定class文件的路徑。
import關鍵字引用的類文件和ClassLoader動態加載類的區別:
import引用類的兩個特點:1、必須存在於本地,當程序運行該類時,內部類裝載器會自動裝載該類。
2、編譯時必須在現場,否則編譯過程會因找不到引用文件而不能正常編譯。
classLoader的特點正好於import相反,而且更自由靈活。
每一個ClassLoader必須有一個父ClassLoader,在裝載Class文件時,子ClassLoader會先請求其父ClassLoader加載該文件,只有當其父ClassLoader找不到該文件時,子ClassLoader才會繼承裝載該類。這是一種安全機制。對於Android而言,最終的apk文件包含的是dex類型的文件,dex文件是將class文件重新打包,打包的規則又不是簡單地壓縮,而是完全對class文件內部的各種函數表,變量表進行優化,產生一個新的文件,即dex文件。因此加載這種特殊的Class文件就需要特殊的類加載器DexClassLoader。
二、DexClassLoader的方法的實用
假設有兩個apk,第一個叫做Host,第二個叫Plugin。Plugin中第一個一個類Plugin,該類中定義了一個addition函數。
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;
}
}
plugin的apk中AndroidManifest文件中,activity必須聲明一個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>
 
將plugin.apk裝載進Android設備中。Host.apk中主activity調用的代碼如下:
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 plugin_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_package, 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();
}
}
運行後得到的結果是:

類加載器在應用中還是用到比較多,還可以基於它設計一種“插件”架構。
Android ApiDemos示例解析(31):App->Preferences->Launching preferences
前給例子介紹了如何使用PreferenceActivity 來顯示修改應用偏好,用戶對Preferences的修改自動存儲在應用對應的 Shared Preferenc
android技巧:如何在android程序中執行adb shell命令
package net.gimite.nativeexe; import java.io.BufferedReader; import java.io.F
理解Android Build系統
前言Android Build 系統是 Android 源碼的一部分。關於如何獲取 Android 源碼,請參照 Android Source 官方網站:http://s
15 個 Android 通用風行框架大全
15 個 Android 通用流行框架大全 1. 緩存 DiskLruCache Java實現基於LRU的磁盤緩存 2.圖片加載 An