與普通程序不同的是,Java程序(class文件)并不是本地的可執行程序。當運行Java程序時(shí),首先運行JVM(Java虛擬機),然后再把Java class加載到JVM里頭運行,負責加載Java class的這部分就叫做Class Loader。通常class文件僅在需要使用時(shí)才加載。 這本身就是一種動(dòng)態(tài)鏈接。
Java作為一種天生的動(dòng)態(tài)鏈接語(yǔ)言,無(wú)法支持靜態(tài)鏈接。但C語(yǔ)言的靜態(tài)庫除了靜態(tài)鏈接的概念外,還隱含了一層意思,即庫中的代碼會(huì )打包到可執行文件中。JAVA中的JAR某種程度上類(lèi)似一個(gè)可執行文件或庫,借用C語(yǔ)言中靜態(tài)庫和動(dòng)態(tài)庫的概念,這里把最終會(huì )合并到生成的JAR文件中的JAR包叫靜態(tài)庫,反之僅僅在編譯中使用,并不打包到生成的JAR包中,運行時(shí)需系統自行提供的JAR包叫動(dòng)態(tài)庫。
C的靜態(tài)鏈接只把需要的代碼復制過(guò)來(lái),而Java用類(lèi)似Fat Jar的方法,把所有的依賴(lài)庫打包到最后的庫中,眉毛胡子一把抓。這個(gè)問(wèn)題可以用ProGuard解決,用它自己的話(huà)說(shuō)是 It detects and removes unused classes, fields, methods, and attributes。
Eclipse中對JAR包的使用方式有兩種,library和user libraries,其中library在工程中通過(guò)add jars...或add external jars...添加,出現在Referenced Libraries中,而user libraries需要在工作空間中管理,再在工程中通過(guò)add library...添加。這兩種使用方式本身并沒(méi)有靜態(tài)庫和動(dòng)態(tài)庫的區別,需要在打包或部署時(shí)再行指定。但user libraries的方式明顯更方便管理多個(gè)工程共同使用的多個(gè)庫,而系統庫往往都有這種特性。
android的apk比JAR更類(lèi)似可執行程序,而且因為標準庫隱藏了很多功能,我們常常需要使用自己構建的系統庫來(lái)編譯。但android的ADT工具并沒(méi)有提供是否將library或user libraries打包的選項。根據我的經(jīng)驗,ADT默認將library打包到apk中,而user libraries則僅用于編譯,運行時(shí)再請求系統加載相關(guān)類(lèi)。哪位同學(xué)有更明確的信息,還望指教,我短期內恐怕不會(huì )有時(shí)間去研究這個(gè)問(wèn)題。
因此,可以這么說(shuō),在android中,library用來(lái)添加靜態(tài)庫,而user libraries用來(lái)管理動(dòng)態(tài)庫。千萬(wàn)不能弄錯了,如果把靜態(tài)庫錯誤地加入動(dòng)態(tài)庫,運行時(shí)會(huì )出現找不到對應的class的錯誤,但因為Java語(yǔ)言的動(dòng)態(tài)鏈接機制,只有運行到庫中代碼時(shí)才會(huì )出錯;反之,如果把動(dòng)態(tài)庫做成了靜態(tài)庫,問(wèn)題就更隱蔽了,可能只是dex文件特別大,而沒(méi)有其它問(wèn)題,也可能因加載了錯誤版本的系統代碼,出現一些稀奇古怪的問(wèn)題。慎之,慎之...
附:向eclispe中添加user Libraries的步驟:
1。點(diǎn)擊eclipse的window菜單,選擇“Preference”
2。在preferences窗口中選擇java->User Libraries,然后點(diǎn)擊窗口右邊的New...按鈕,在彈出的子窗口中輸入user library的名稱(chēng),此時(shí)在user libraries窗口中會(huì )出現新加的library名稱(chēng)。
3。向該user library中添加jar包。選中my_lib,然后點(diǎn)擊Add JARS...按鈕,選擇你要添加的jar后,點(diǎn)擊“打開(kāi)”按鈕,則my_lib庫中就會(huì )出現你剛添加的jar文件信息。
4。最后點(diǎn)擊窗口下的“OK”按鈕,完成user library的添加和其jar的添加。
聯(lián)系客服