編輯: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(); } }
運行後得到的結果是:
類加載器在應用中還是用到比較多,還可以基於它設計一種“插件”架構。
前給例子介紹了如何使用PreferenceActivity 來顯示修改應用偏好,用戶對Preferences的修改自動存儲在應用對應的 Shared Preferenc
package net.gimite.nativeexe; import java.io.BufferedReader; import java.io.F
前言Android Build 系統是 Android 源碼的一部分。關於如何獲取 Android 源碼,請參照 Android Source 官方網站:http://s
15 個 Android 通用流行框架大全 1. 緩存 DiskLruCache Java實現基於LRU的磁盤緩存 2.圖片加載 An