標籤:android http io os 使用 ar java strong for
原始地址: http://www.2cto.com/kf/201403/284689.html
本文記述“柯元旦”Android核心剖析中基於類裝載器的“外掛程式”架構。
外掛程式的概念:
1、外掛程式不能獨立運行,而必須運行於一個宿主程式中,即由宿主程式去調用外掛程式程式。
2、外掛程式一般可以獨安裝。
3、宿主程式中可以管理不同的外掛程式,包括查看外掛程式的數目,禁用或者使用某個外掛程式。
4、宿主程式應該保證外掛程式的向下相容性,即新版本的宿主程式可以運行較老版本的外掛程式。
下面詳細看一下這種架構:
1、宿主程式:
建立Android項目PluginDevAndroid
2、外掛程式項目1:Plugin1
3、外掛程式項目2:
4、綜述:
4.1、介面類一般定義在宿主專案中,比如本例中的IPluginDev.java
4.2、外掛程式項目需要應用IPluginDev時,則必須通過一個外部的jar包,並且該jar包是以Library的形式被添加到Plugin項目的build Path,而不是以“外部的”jar方式添加。
4.3、宿主程式想要知道系統中有哪些外掛程式,可以定義一個Action,本例中使用的是如下action。
這樣的話,宿主程式就可以通過PackageManager類的queryIntentActivities函數查詢相關的外掛程式的列表了。
得到了外掛程式的PackageName,就可以訪問外掛程式的資源內容。例如:
?
| 12345 |
Resources res = pm.getResourcesForApplication(packageName);int id = 0;id = res.getIdentifier(version, string, packageName);String version = res.getString(id);Log.d(hlwang, MainActivity test version is:+version); |
這段代碼中,首先擷取外掛程式的Resource對象,接著得到名稱為version欄位的字串id值,然後再調用getString獲得該變數的值,於是宿主程式就知道外掛程式程式中的資源內容了。
關鍵代碼:
?
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
private void test(){ Intent intent = new Intent(com.example.plugindevandroid.plugin,null); final PackageManager pm = getPackageManager(); final List<resolveinfo> plugins = pm.queryIntentActivities(intent, 0); for(ResolveInfo r:plugins){ ActivityInfo activityInfo = r.activityInfo; String div = System.getProperty(path.separator); String packageName = activityInfo.packageName; String packageName0 = getPackageName(); String dexPath = activityInfo.applicationInfo.sourceDir; String dexOutputDir1 = activityInfo.applicationInfo.dataDir; String dexOutputDir2 = getApplicationInfo().dataDir; String libPath = activityInfo.applicationInfo.nativeLibraryDir; Log.d(hlwang, MainActivity test div is:+div +,packageName is:+packageName +,packageName0 is:+packageName0 +,dexPath is:+dexPath +,dexOutputDir1 is:+dexOutputDir1 +,dexOutputDir2 is:+dexOutputDir2 +,libPath is:+libPath); DexClassLoader dexCl = new DexClassLoader(dexPath, dexOutputDir2, libPath, getClassLoader()); Log.d(hlwang, MainActivity test clazzName is:+packageName+.PluginVersion); try{ Class clazz = dexCl.loadClass(packageName+.PluginVersion); IPluginDev plugin = (IPluginDev) clazz.newInstance(); String name = plugin.getName(); Log.d(hlwang, MainActivity test name is:+name); Resources res = pm.getResourcesForApplication(packageName); int id = 0; id = res.getIdentifier(version, string, packageName); String version = res.getString(id); Log.d(hlwang, MainActivity test version is:+version); PluginObject p = new PluginObject(); p.name = name; p.version = version; Log.d(hlwang, MainActivity test p is:+p); mList.add(p); }catch(Exception e){ Log.d(hlwang, MainActivity exception eeeeeeeeeeeee); e.printStackTrace(); } } Log.d(hlwang, MainActivity test list size is:+mList.size()); setListAdapter(new ArrayAdapter<pluginobject>(this, android.R.layout.simple_list_item_1, mList)); }</pluginobject></resolveinfo> |
這段代碼中,首先得到外掛程式的List列表。
然後得到外掛程式的packageName,以及外掛程式的dexPath目錄。
再次,得到dexOutputDir目錄。
libPath一般只c/c++使用的庫檔案。
DexClassLoader的參數意義:
dexPath:外掛程式apk或者jar包檔案的路徑
dexOutputDir:將目標apk或者jar包解壓的檔案的存放目錄。因為宿主程式只對本應用程式所在的目錄由存取許可權。
運行:
轉-基於外掛程式開發的Android實現流程