編輯:Android開發實例
插件的引入
1、UI方面有些自定義的通用控件代碼,並不局限於一個項目中使用,當需要共享使用時雖然可以采用源碼方式合入新項目,但是這種原始方式增加代碼布局上的復雜程度的同時,也增大了通用控件的不安全性。 2、有些功能性模塊,或是第三方開發,或是分階段開發的,為了方便程序的功能擴展,我們同樣考慮將功能代碼封裝為插件包的形式。 那麼在Android中是否支持插件呢?也就是是否支持類似Windows和Symbian平台的lib和dll等庫方式呢?答案是肯定的,在Android中支持的插件庫,可以是由C/C++開發的JNI形式,也可以是由java代碼開發的jar形式(也可以是android封包完成的apk文件)。由於JNI需要涉及Android NDK,這裡不做介紹,本文只針對jar插件。 加載jar插件的方式 雖然在加載jar插件方式之前,我們應該考慮jar插件的創建,但是由於jar加載方式的不同,決定了jar插件創建形式的不同。目前加載jar插件的方式有兩類:一類是跟加載SDK api的Android.jar一樣的靜態加載方式;另一類是運行時動態加載方式。前者是編譯過程中就必須要jar文件存在,後者是運行時通過反射機制來動態調用。下面我們分別闡述。 靜態加載jar插件 靜態jar插件的創建 靜態jar插件的創建,可以只是由一個簡單的java類文件編譯生成,也可以從一個完整的工程中導出生成。 假設有一個沒有用到Android API的 test.java文件放置在c盤根目錄下面,那麼在安裝jdk的PC上我們可以通過cmd命令行來生成一個jar文件 //編譯test.java,生成test.class C:\>javac test.java //壓縮test.class生成jar文件 C:\>jar cvf test.jar test.class 標明清單(manifest) 增加:test.class(讀入= 267) (寫出= 213)(壓縮了 20%) //查看生成的jar文件中具體有哪些內容 C:\>jar tvf test.jar 0 Fri Sep 23 11:21:34 CST 2011 META-INF/ 75 Fri Sep 23 11:21:34 CST 2011 META-INF/MANIFEST.MF 267 Thu Sep 22 17:56:42 CST 2011 test.class 通過如上步驟一個最簡單jar插件就生成了。下面在看如何從一個完整工程中生成一個jar文件,當然也可以通過cmd命令行的方式來實現,但是對於工程來說,涉及代碼文件多,在Eclipse中又提供了簡易操作的情況下,我們自然優先選擇Eclipse來圖形化實現jar文件的生成。本想自己按步驟小結下,但是發現網上很多博客整理的很詳細了,我在這裡就引用http://hi.baidu.com/lovewjlove/blog/item/95d74560ebacdbd68db10d90.html 博文中的內容吧。 1. 首先在Eclipse中打開項目, 右鍵點擊項目,選擇“Export”; 2. 選擇Java/JAR file,Next; 3. Select the resources to export中可以選擇你想要包含的項目文件夾,一些不必要的文件夾就無需放進去了,免得增大空間; 這裡有幾個選項: * Export generated class files and resources 表示只導出生成的.class文件和其他資源文件 * Export all output folders for checked projects 表示導出選中項目的所有文件夾 * Export java source file and resouces 表示導出的jar包中將包含你的源代碼*.java,如果你不想洩漏源代碼,那麼就不要選這項了 * Export refactorings for checked projects 把一些重構的信息文件也包含進去 在Select the export destination中選擇導出的jar的路徑,Next 4. 下一頁可以選擇是否導出那些含有警告warning或者錯誤errors的*.class文件。一般不用理他,Next 5. 下一個頁面裡可以對項目做一些配置 * Generate the manifest file是系統幫我們自動生成MANIFEST.MF文件,如果你的項目沒有引用其他class-path,那可以選擇這一項; * Use existing mainfest from workspace。這是可以選擇我們自定義的.MF文件,格式如上所寫; * Seal content。要封裝整個jar或者指定的包packet; * Main class。這裡可以選擇你的程序入口,將來打包出來的jar就是你這個入口類的執行結果; 配置完點擊Finish,工程的jar文件就生成了。 博文中只是針對java工程,對於android工程我們自然也是可以通過上述方法完成靜態jar文件的生成。 靜態jar插件的使用 通過上面靜態jar插件的創建步驟,我們生成了一個drawcolor.jar的jar插件,下面我們來演示下如何將這個文件加載到Android app中進行使用。 首先,拷貝jar插件至工程目錄。在android工程根目錄創建一個lib文件夾,將該drawcolor.jar拷貝至lib文件夾下; 其次,工程中添加jar插件。右擊工程,通過屬性菜單,打開Java Build Path對話框,選中Libraries,添加JARS,在彈出的對話框中選擇lib/drawcolor.jar文件(也可以通過項目右鍵點擊Build Path,Build Path–> Libraries–> Add JARs,選擇第三方的jar包,),結果如下 第三,調用jar中的操作。通過上述步驟之後,在Eclipse的Project Explorer下面就可以看到jar包中的類和成員了,與使用Android.jar內的API一樣使用,具體就不給出示例了。 第四,將添加的jar打包到apk中。由於SDK的API在運行環境中(模擬器和手機上)已經有插件存在了,所以我們不用打包到apk中,而我們自己添加的jar,就必須要打包到apk中,否則運行時會報沒有找到包的錯誤。打包到apk需要做如下操作 在工程目錄下找到.classpath文件,因為我們這裡添加的jar位於lib/drawcolor.jar,所以查看文件中是否有如下一行 <classpathentry kind="lib" path="lib/drawcolor.jar"/> 假如有就可以了,假如是其他的,就要把他更改過來,比如http://www.yoyong.com/archives/tag/android-%E6%89%93%E5%8C%85%E7%AC%AC%E4%B8%89%E6%96%B9jar博文中提到的一樣。 懷疑這個跟Eclipse的版本有關吧,我的編譯環境下,這個在工程中添加jar插件步驟時已經在工程的.classpath文件修改為需求的樣子了。 以上就實現了靜態加載jar插件。 動態加載jar插件 動態jar插件的創建 動態jar插件的創建相對比靜態jar多了一個步驟,因為Android虛擬機是基於dex的,所以我們的class不能簡單的調用jar命令壓縮就可以了,而是需要使用sdk\platform-tools目錄下的dx工具來進行類型轉換。下面演示單一類文件AddFunc.java的生成jar插件使用命令行的過程。 <!--[if !supportLists]-->1、 <!--[endif]-->使用javac命令編譯生成AddFunc.class文件 <!--[if !supportLists]-->2、 <!--[endif]-->由於AddFunc類的包目錄為com.demo.jar,所以需要將AddFunc.class文件拷貝至sdk\platform-tools\com\demo\jar文件夾下面 <!--[if !supportLists]-->3、 <!--[endif]-->使用dx命令,生成jar插件文件,上述步驟的命令如下 C:\>javac AddFunc.java C:\>dx --dex --output=AddFunc.jar com/demo/jar/AddFunc.class C:\>jar tvf D:\Android\sdk\platform-tools\AddFunc.jar 72 Fri Sep 23 14:28:48 CST 2011 META-INF/MANIFEST.MF 964 Fri Sep 23 14:28:50 CST 2011 classes.dex 通過上述步驟在sdk\platform-tools上面就有一個AddFunc.jar文件了。在這裡需要說明的是AddFunc.class必須按照包名放置,否則生成jar會報錯。 其實假如本身就在Android工程下面,那麼可以現在eclipse下面先編譯程序,後在Bin目錄下面,自然就按包名,放置了class文件,再將需要的class文件包含文件目錄拷貝至sdk\platform-tools目錄下就好了。假設我們需要打包兩個class,就可以通過如下命令實現 C:\>dx --dex --output=AddFunc.jar com/demo/jar/AddFunc.class com/demo/jar/GameView.class 經過查詢,明顯比上面這個classes.dex文件大多了,具體如下 C:\>jar tvf D:\Android\sdk\platform-tools\AddFunc.jar 72 Fri Sep 23 14:38:06 CST 2011 META-INF/MANIFEST.MF 1752 Fri Sep 23 14:38:06 CST 2011 classes.dex 好了,我們需要的動態jar插件就形成了。 動態jar插件的使用 如上所述,我們生成了需要動態jar插件,如同java中動態加載使用ClassLoader類動態加載一樣,在Android我們需要使用DexClassLoader來通過反射機制動態加載。 相對來說假如動態jar插件創建正確,這一步就沒什麼難題了,就全交給代碼來說明吧。 AddFunc的源代碼為 package com.demo.jar; import android.util.Log; public class AddFunc { public AddFunc() { Log.i("AddFunc", "AddFunc class Init"); } public int Add(int a, int b) { int c = a + b; Log.i("AddFunc", "Add result is "+c); return c; } } 以上的代碼生成動態jar插件後,在模擬器通過cmd如下命令,將jar插件放置到運行壞境中,本文是將其放置在模擬器的sdcard根目錄,具體如下 C:\>adb push addFunc.jar sdcard/ 6 KB/s (1149 bytes in 0.187s) 這樣,就可以在代碼中使用反射機制調用jar中的方法了,具體的Android工程中動態調用jar插件的代碼如下 package com.demo.jar.runloadjarDemo; import java.io.File; import java.lang.reflect.Method; import dalvik.system.DexClassLoader; import android.app.Activity; import android.os.Bundle; public class RunLoadJarDemoActivity extends Activity { /** Called when the activity is first created. */ Class myClass =null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { File file = new File("/sdcard/AddFunc.jar"); // File file = new File("/sdcard/drawView.apk"); if(file.exists()) { DexClassLoader cl = new DexClassLoader(file.toString(), getFilesDir().getAbsolutePath(), null, ClassLoader.getSystemClassLoader().getParent()); myClass = cl.loadClass("com.demo.jar.AddFunc"); Object obj = myClass.newInstance(); Class[] params = new Class[2]; params[0] = Integer.TYPE; params[1] = Integer.TYPE; Method action = myClass.getMethod("Add", params); int ret = (Integer)action.invoke(obj, 15, 20); } } catch (Exception ex) { ex.printStackTrace(); } } } 其實從原理上來說,如上生成的動態jar插件,跟apk的生成是同一個道理,所以假設我們不想通過繁瑣的dx工具,那麼也可以直接由eclipse生成apk,然後通過動態加載的方法來使用apk中的類和方法,本人測試過也是可行的。 好了,至此將Android app中加載jar插件的問題就介紹到這裡,如果大家覺得如上的代碼調用反射太過繁瑣,那麼可以通過設計接口的方法來將反射變得簡單,至於這個話題就不在本文進行闡述了。本隨筆原文和demo,詳見鏈接
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
本文實例講述了Android學習筆記之應用單元測試。分享給大家供大家參考,具體如下: 第一步:在AndroidManifest.xml中加入如下兩段代碼: &
今天來實現以下大眾點評客戶端的橫向listview二級列表,先看一下樣式。 這種橫向的listview二級列表在手機軟件上還不太常見,但是使用過平板的
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用