android結構圖
㈠ 移動開發基礎教程:Android是什麼 安卓開發
Android是基於Linux內核的操作系統,是谷歌公司在2007年11月5日公布的手機操作系統,早期由谷歌開發,後由開放手持設備聯盟(Open Handset Alliance)開發。它採用了軟體堆層(software stack,又名以軟體疊層)的架構,主要分為三部分。底層Linux內核只提供基本功能;其他的應用軟體則由各公司自行開發,部分程序以java編寫。
一、簡介
BlackBerry和iPhone都提供了受歡迎的、高容量的移動平台,但是卻分別針對兩個不同的消費群體。BlackBerry是企業業務用戶的不二選擇。但是,作為一種消費設備,它在易用性和 「新奇特性」 方面難以和iPhone抗衡。Android則是一個年輕的、有待開發的平台,它有潛力同時涵蓋行動電話的兩個不同消費群體,甚至可能縮小工作和娛樂之間的差別。
如今,很多基於網路或有網路支持的設備都運行某種Linux內核。這是一種可靠的平台:可經濟有效地進行部署和提供支持,並且可直接作為面向部署的良好的設計方法。這首攜鏈些設備的UI通常是基於HTML的,可通過PC或Mac瀏覽器查看。但並不是每個設備都需要通過一個常規的計算設備來控制。想像一下傳統的家用電器,例如電爐、微波爐或麵包機。如果您者孫的家用電器由Android控制,並且有一個彩色觸摸屏,會怎麼樣?如果電爐上有一個Android UI,那麼操控者甚至可以烹飪點什麼東西。
二、Android術語
在Eclipse環境中開發Android應用程序需要了解Eclipse環境和Android平台的知識。了解以下術語會有助於用Eclipse插件開發Android應用程序。
Open Handset Alliance
這是一個由谷歌公司主導的組織,它由許多公共和私人組織組成。
Android
這是Open Handset Alliance的主打產品。它是一種針對移動設備的開放源碼操作環境。
模擬器
模擬另一個系統的軟體工具—這常常是在個人計算機(IBM、Mac、Linux)上運行的一個環境,它模擬另一個環境,比如移動計算設備。
Linux
一種開放源碼的操作系統內核,許多計算平台都使用這種操作系統,包括伺服器、桌面計算機、網路設備和移動計算設備。Android在Linux內核上運行。
Dalvik Virtual Machine
Dalvik VM是Android產品組合中的一種操作環境,它在運行時解釋應用程序代碼。Dalvik VM與Java VM相似,但是兩者不兼容。
三、Android簡史
Android平台是Open Handset Alliance的成果,Open Handset Alliance 組織由一群共同致力於構建更好的行動電話的公司組成。這個組織由谷歌領導,包括移動運營商、手持設備製造商、零部件製造商、軟體解決方案和平台提供商以及市場營銷公司。從軟體開發的觀點看,Android正處在開源領域的中心位置。
市場上第一款支持Android的手機是由HTC製造並由T-Mobile供應的G1。這款隱山設備從設想到推出花了大約一年的時間,惟一可用的軟體開發工具是一些實行增量改進的SDK發行版。隨著G1發行日的臨近,Android團隊發布了SDK V1.0,用於這個新平台的應用程序也浮出水面。
為了鼓勵創新,谷歌舉辦了兩屆「Android Developer Challenges」,為優勝的參賽作品提供數百萬美金的獎勵。G1 問世幾個月之後,隨後就發布了Android Market,它使用戶可以瀏覽應用程序,並且可以將應用程序直接下載到他們的手機上。經過大約 18 個月,一個新的移動平台進入公眾領域。
四、Android平台
Android平台被稱為一個產品組合,因為它是一系列組件的集合,包括:
基於Linux內核的操作系統 Java編程環境 工具集,包括編譯器、資源編譯器、調試器和模擬器 用來運行應用程序的Dalvik VM
Android有豐富的功能,因此很容易與桌面操作系統混淆。Android是一個分層的環境,構建在Linux內核的基礎上,它包括豐富的功能。UI 子系統包括:
窗口 視圖 用於顯示一些常見組件(例如編輯框、列表和下拉列表)的小部件。
Android包括一個構建在WebKit基礎上的可嵌入瀏覽器,iPhone 的Mobile Safari瀏覽器同樣也是以WebKit為基礎。
Android提供多種連接選項,包括WiFi、藍牙和通過蜂窩(cellular)連接的無線數據傳輸(例如GPRS、EDGE 和3G)。Android應用程序中一項流行的技術是鏈接到谷歌地圖,以便在應用程序中顯示地址。Android軟體棧還提供對基於位置的服務(例如GPS)和加速計的支持,不過並不是所有的Android設備都配備了必需的硬體。另外還有攝像支持。
過去,移動應用程序努力向桌面應用程序看齊的兩個領域分別是圖形/媒體和數據存儲方法。Android通過提供對2D和3D圖形的內置支持,包括OpenGL 庫,解決了圖形方面的挑戰。由於Android平台包括流行的開源SQLite 資料庫,因此緩解了數據存儲的負擔。圖1顯示一個簡化的Android軟體層次結構。
五、應用程序架構
如前所述,Android運行在Linux內核上。Android應用程序是用Java編程語言編寫的,它們在一個虛擬機(VM)中運行。需要注意的是,這個VM並非您想像中的JVM,而是Dalvik Virtual Machine,這是一種開源技術。每個Android應用程序都在Dalvik VM的一個實例中運行,這個實例駐留在一個由Linux內核管理的進程中,如下圖所示。
Android應用程序由一個或多個組件組成:
活動
具有可視UI的應用程序是用活動實現的。當用戶從主屏幕或應用程序啟動器選擇一個應用程序時,就會開始一個動作。
服務
服務應該用於任何需要持續較長時間的應用程序,例如網路監視器或更新檢查應用程序。
內容提供程序
可以將內容提供程序看作資料庫伺服器。內容提供程序的任務是管理對持久數據的訪問,例如SQLite資料庫。如果應用程序非常簡單,那麼可能不需要創建內容提供程序。如果要構建一個較大的應用程序,或者構建需要為多個活動或應用程序提供數據的應用程序,那麼可以使用內容提供程序實現數據訪問。
廣播接收器
Android應用程序可用於處理一個數據元素,或者對一個事件(例如接收文本消息)做出響應。
Android應用程序是連同一個AndroidManifest.xml文件一起部署到設備的。AndroidManifest.xml包含必要的配置信息,以便將它適當地安裝到設備。它包括必需的類名和應用程序能夠處理的事件類型,以及運行應用程序所需的許可。例如,如果應用程序需要訪問網路 — 例如為了下載一個文件 — 那麼manifest文件中必須顯式地列出該許可。很多應用程序可能啟用了這個特定的許可。這種聲明式安全性有助於減少惡意應用程序損害設備的可能性。
六、所需工具
開始開發Android應用程序的最簡捷的方式是下載AndroidSDK 和EclipseIDE。Android開發可以在微軟Windows、Mac OS X 或Linux上進行。
本文假設您使用的是Eclipse IDE和用於Eclipse的Android Developer Tools插件。Android應用程序是用Java語言編寫的,但是是在Dalvik VM(非Java虛擬機)中編譯和執行的。在Eclipse中用Java語言編程非常簡單;Eclipse 提供一個豐富的Java環境,包括上下文敏感幫助和代碼提示。Java 代碼通過編譯後,Android Developer Tools 可確保適當地將它打包,包括AndroidManifest.xml 文件。
雖然沒有Eclipse和Android Developer Tools插件也可以開發Android應用程序,但是那樣就需要熟悉Android SDK。
AndroidSDK 是作為一個ZIP文件發布的,可以將該文件解壓到硬碟上的一個目錄中。由於有多個SDK更新,建議有意識地組織開發環境,以便在不同的SDK安裝之間輕松地切換。
SDK 包括:
android.jar
Java 歸檔文件,其中包含構建應用程序所需的所有的Android SDK 類。
documention.html和docs目錄
本地和網上提供的SDK文檔。這些文檔的主要形式為JavaDocs,以便於在SDK中導航大量的包。文檔還包括一個高級開發指南和Android社區的鏈接。
Samples目錄
Samples子目錄包含各種應用程序的源代碼,包括ApiDemo,該應用程序演示了很多API。這個示例應用程序可以作為Android應用程序開發的良好起點。
Tools目錄
包含所有用於構建Android應用程序的命令行工具。最常用、最有用的工具是adb實用程序(Android Debug Bridge)。
usb_driver
該目錄包含將開發環境連接到支持Android的設備(例如G1或Android Dev 1解鎖開發手機)所需的驅動程序。只有Windows平台的開發人員才需要這些文件。
Android應用程序可以在實際的設備上運行,也可以在Android SDK 附帶的Android Emulator上運行。圖 3 顯示Android Emulator 的主屏幕。
七、Android Debug Bridge
adb實用程序支持一些可選命令行參數,以提供強大的特性,例如復制文件到設備或從設備復制文件。可以使用shell命令行參數連接到手機本身,並發送基本的shell命令。圖 4 顯示在通過USB線連接到Windows筆記本電腦的一個實際設備上運行的adb shell命令。
在這個shell環境中,可以:
顯示網路配置,網路配置可顯示多個網路連接。注意這多個網路連接:
lo是本地或loopback連接。
tiwlan0是WiFi連接,該連接由本地DHCP伺服器提供一個地址。
顯示PATH環境變數的內容。
執行su命令,以成為超級用戶。
將目錄改為/data/app,其中存放用戶應用程序。
列出包含某個應用程序的目錄。Android應用程序文件實際上是歸檔文件,可通過WinZip之類的軟體查看。擴展名為apk。
發出ping命令,查看Google.com是否可用。
從相同的命令提示符環境中,還可以與SQLite 資料庫交互,啟動程序以及執行許多其他系統級任務。想像一下您正在連接到電話,因此這是非常了不起的功能。
㈡ 請教Android中資料庫表結構
SQPte 一個非常流行的嵌入式資料庫,它支持 SQL 語言,並且只利用很少的內存就有很好的性能。此外它還是開源的,任何人都可以使用它。許多開源項目((Mozilla, PHP, Python)都使用了 SQPte. SQPte 由以下幾個組件組成:SQL 編譯器、內核、後端以及附件。SQPte 通過利用虛擬機和虛擬資料庫引擎(VDBE),使調試、修改和擴展 SQPte 的內核變得更加方便。 圖 1. SQPte 內部結構 SQPte 基本上符合 SQL-92 標准,和其他的主要 SQL 資料庫沒什麼區別。它的優點就是高效,Android 運行時環境包含了完整的 SQPte。 SQPte 和其他資料庫最大的不同就是對數據類型的支持,創建一個表時,可以在 CREATE TABLE 語句中指定某列的數據類型,但是你可以把任何數據類型放入任何飢模列中。當某個值插入資料庫時,SQPte 將檢查它的類型。如果該類型與關聯的列不匹配,則 SQPte 會嘗試將該值轉換成該列的類型。如果不能轉換,則該值將作為其本身具有的類型存儲。比如可以把一個字元串(String)放入 INTEGER 列。SQPte 稱這為“弱類型”(manifest typing.)。 此外,SQPte 不支持一些標准襪肢孝的 SQL 功能,特別是外鍵約束(FOREIGN KEY constrains),嵌套 transcaction 和 RIGHT OUTER JOIN 和 FPL OUTER JOIN, 還有一些 ALTER TABLE 功能。 除了上述功能外,SQPte 是一個完整的 SQL 系統,擁有完整的觸發器,交易等等。 Android 集成了 SQPte 資料庫 Android 在運行時(run-time)集成了告稿 SQPte,所以每個 Android 應用程序都可以使用 SQPte 資料庫。對於熟悉 SQL 的開發人員來時,在 Android 開發中使用 SQPte 相當簡單。但是,由於 JDBC 會消耗太多的系統資源,所以 JDBC 對於手機這種內存受限設備來說並不合適。因此,Android 提供了一些新的 API 來使用 SQPte 資料庫,Android 開發中,程序員需要學使用這些 API。 資料庫存儲在 data/< 項目文件夾 >/databases/ 下。 Android 開發中使用 SQPte 資料庫 Activites 可以通過 Content Provider 或者 Service 訪問一個資料庫。下面會詳細講解如果創建資料庫,添加數據和查詢資料庫。 創建資料庫 Android 不自動提供資料庫。在 Android 應用程序中使用 SQPte,必須自己創建資料庫,然後創建表、索引,填充數據。Android 提供了 SQPteOpenHelper 幫助你創建一個資料庫,你只要繼承 SQPteOpenHelper 類,就可以輕松的創建資料庫。SQPteOpenHelper 類根據開發應用程序的需要,封裝了創建和更新資料庫使用的邏輯。SQPteOpenHelper 的子類,至少需要實現三個方法: 構造函數,調用父類 SQPteOpenHelper 的構造函數。這個方法需要四個參數:上下文環境(例如,一個 Activity),資料庫名字,一個可選的游標工廠(通常是 NPl),一個代表你正在使用的資料庫模型版本的整數。 onCreate()方法,它需要一個 SQPteDatabase 對象作為參數,根據需要對這個對象填充表和初始化數據。 onUpgrage() 方法,它需要三個參數,一個 SQPteDatabase 對象,一個舊的版本號和一個新的版本號,這樣你就可以清楚如何把一個資料庫從舊的模型轉變到新的模型。 下面示例代碼展示了如何繼承 SQPteOpenHelper 創建資料庫: pubPc class DatabaseHelper extends SQPteOpenHelper { DatabaseHelper(Context context, String name, CursorFactory cursorFactory, int version) { super(context, name, cursorFactory, version); } @Override pubPc void onCreate(SQPteDatabase db) { // TODO 創建資料庫後,對資料庫的操作 } @Override pubPc void onUpgrade(SQPteDatabase db, int PdVersion, int newVersion) { // TODO 更改資料庫版本的操作 } @Override pubPc void onOpen(SQPteDatabase db) { super.onOpen(db); // TODO 每次成功打開資料庫後首先被執行 } } 接下來討論具體如何創建表、插入數據、刪除表等等。調用 getReadableDatabase() 或 getWriteableDatabase() 方法,你可以得到 SQPteDatabase 實例,具體調用那個方法,取決於你是否需要改變資料庫的內容: db=(new DatabaseHelper(getContext())).getWritableDatabase(); return (db == nPl) ? false : true; 上面這段代碼會返回一個 SQPteDatabase 類的實例,使用這個對象,你就可以查詢或者修改資料庫。 當你完成了對資料庫的操作(例如你的 Activity 已經關閉),需要調用 SQPteDatabase 的 Close() 方法來釋放掉資料庫連接。 創建表和索引 為了創建表和索引,需要調用 SQPteDatabase 的 execSQL() 方法來執行 DDL 語句。如果沒有異常,這個方法沒有返回值。 例如,你可以執行如下代碼: db.execSQL("CREATE TABLE mytable (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, value REAL);"); 這條語句會創建一個名為 mytable 的表,表有一個列名為 _id,並且是主鍵,這列的值是會自動增長的整數(例如,當你插入一行時,SQPte 會給這列自動賦值),另外還有兩列:title( 字元 ) 和 value( 浮點數 )。 SQPte 會自動為主鍵列創建索引。 通常情況下,第一次創建資料庫時創建了表和索引。如果你不需要改變表的 schema,不需要刪除表和索引 . 刪除表和索引,需要使用 execSQL() 方法調用 DROP INDEX 和 DROP TABLE 語句。 給表添加數據 上面的代碼,已經創建了資料庫和表,現在需要給表添加數據。有兩種方法可以給表添加數據。 像上面創建表一樣,你可以使用 execSQL() 方法執行 INSERT, UPDATE, DELETE 等語句來更新表的數據。execSQL() 方法適用於所有不返回結果的 SQL 語句。例如: db.execSQL("INSERT INTO widgets (name, inventory)"+ "VALUES ('Sprocket', 5)"); 另一種方法是使用 SQPteDatabase 對象的 insert(), update(), delete() 方法。這些方法把 SQL 語句的一部分作為參數。示例如下: ContentValues cv=new ContentValues(); cv.put(Constants.TITLE, "example title"); cv.put(Constants.VALUE, SensorManager.GRAVITY_DEATH_STAR_I); db.insert("mytable", getNPlCPumnHack(), cv); update()方法有四個參數,分別是表名,表示列名和值的 ContentValues 對象,可選的 WHERE 條件和可選的填充 WHERE 語句的字元串,這些字元串會替換 WHERE 條件中的“?”標記。update() 根據條件,更新指定列的值,所以用 execSQL() 方法可以達到同樣的目的。 WHERE 條件和其參數和用過的其他 SQL APIs 類似。例如: String[] parms=new String[] {"this is a string"}; db.update("widgets", replacements, "name=?", parms); delete() 方法的使用和 update() 類似,使用表名,可選的 WHERE 條件和相應的填充 WHERE 條件的字元串。 查詢資料庫 類似 INSERT, UPDATE, DELETE,有兩種方法使用 SELECT 從 SQPte 資料庫檢索數據。 1 .使用 rawQuery() 直接調用 SELECT 語句; 使用 query() 方法構建一個查詢。 Raw Queries正如 API 名字,rawQuery() 是最簡單的解決方法。通過這個方法你就可以調用 SQL SELECT 語句。例如: Cursor c=db.rawQuery( "SELECT name FROM sqPte_master WHERE type='table' AND name='mytable'", nPl); 在上面例子中,我們查詢 SQPte 系統表(sqPte_master)檢查 table 表是否存在。返回值是一個 cursor 對象,這個對象的方法可以迭代查詢結果。如果查詢是動態的,使用這個方法就會非常復雜。例如,當你需要查詢的列在程序編譯的時候不能確定,這時候使用 query() 方法會方便很多。 RegPar Queriesquery() 方法用 SELECT 語句段構建查詢。SELECT 語句內容作為 query() 方法的參數,比如:要查詢的表名,要獲取的欄位名,WHERE 條件,包含可選的位置參數,去替代 WHERE 條件中位置參數的值,GROUP BY 條件,HAVING 條件。除了表名,其他參數可以是 nPl。所以,以前的代碼段可以可寫成: String[] cPumns={"ID", "inventory"}; String[] parms={"snicklefritz"}; Cursor resPt=db.query("widgets", cPumns, "name=?",parms, nPl, nPl, nPl); 使用游標不管你如何執行查詢,都會返回一個 Cursor,這是 Android 的 SQPte 資料庫游標,使用游標,你可以:通過使用 getCount() 方法得到結果集中有多少記錄;通過 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍歷所有記錄;通過 getCPumnNames() 得到欄位名;通過 getCPumnIndex() 轉換成欄位號;通過 getString(),getInt() 等方法得到給定欄位當前記錄的值;通過 requery() 方法重新執行查詢得到游標;通過 close() 方法釋放游標資源;例如,下面代碼遍歷 mytable 表 Cursor resPt=db.rawQuery("SELECT ID, name, inventory FROM mytable"); resPt.moveToFirst(); while (!resPt.isAfterLast()) { int id=resPt.getInt(0); String name=resPt.getString(1); int inventory=resPt.getInt(2); // do something usefP with these resPt.moveToNext(); } resPt.close(); 在 Android 中使用 SQPte 資料庫管理工具 在其他資料庫上作開發,一般都使用工具來檢查和處理資料庫的內容,而不是僅僅使用資料庫的 API。使用 Android 模擬器,有兩種可供選擇的方法來管理資料庫。首先,模擬器綁定了 sqPte3 控制台程序,可以使用 adb shell 命令來調用他。只要你進入了模擬器的 shell,在資料庫的路徑執行 sqPte3 命令就可以了。資料庫文件一般存放 在:/data/data/your.app.package/databases/your-db-name如果你喜歡使用更友好的工具,你 可以把資料庫拷貝到你的開發機上,使用 SQPte-aware 客戶端來操作它。這樣的話,你在一個資料庫的拷貝上操作,如果你想要你的修改能反映到設備上,你需要把資料庫備份回去。把資料庫從設備上考出來,你可以使 用 adb pPl 命令(或者在 IDE 上做相應操作)。存儲一個修改過的資料庫到設備上,使用 adb push 命令。一個最方便的 SQPte 客戶端是 FireFox SQPte Manager 擴展,它可以跨所有平台使用。 圖 2. SQPte Manager 結束語 如果你想要開發 Android 應用程序,一定需要在 Android 上存儲數據,使用 SQPte 資料庫是一種非常好的選擇。本文介紹了如何在 Android 應用程序中使用 SQPte 資料庫 ,主要介紹了在 Android 應用程序中使用 SQPte 創建資料庫和表、添加數據、更新和檢索數據,還介紹了比較常用的 SQPte 管理工具,通過閱讀本文,你可以在 Android 中輕松操作 SQPte 資料庫。
㈢ Android核心模塊結構層次有哪些呢
Android作為一個移動設備的平台,其軟體層次結構包括了一個操作系統(OS),中間件(MiddleWare)和應用程序(Application)。
根據Android的軟體框圖,其Android核心模塊結構自下而上分為以下幾個層次:
第一、操作系統層(OS)
第二、各種庫(Libraries)和Android 運行環境(RunTime)
第三、應用程序框架(Application Framework)
第四、應用程序(Application)
㈣ android studio集成cordova和安裝cordova有什麼不同
一般Android項目結構和目錄結構一樣,是這樣的:
MyApp
|--build.gradle
|--settings.gradle
|--app
|-- build.gradle
|-- build
|-- libs
|-- src
|-- main
|--java
| |-- com.package.myapp
|--res
|-- drawable
|-- layout
|-- etc
由Cordova創建的項目的目錄結構是這樣的(項目結構見上圖)
看起來很亂是不是。但是不影響使用,實際上也沒必要非要改成標准格式。因為Gradle已經幫我們在配置腳本中寫好了相關配置,它知道如何找到需要的文件。
按照標準的Gradle教程,項目即使沒有任何模塊(mole),Android Studio也會為我們生成一個對應於項目的build.gradle腳本文件的。而觀察圖1,Android Studio打開的Cordova項目中卻沒有,編譯構建工作也可以正常進行,說明這個文件不是必須的。
它是在andorid、CordovaLib模塊中的build.gradle腳本中的android任務的sourceSets的main屬性,其中定義了Android Studio項目目錄結構和真實目錄的對應關系。比如android模塊下的build.gradle是這樣的:
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
詳細請參考G文第一篇 '保持舊的Eclipse文件結構' 部分。
可以看到,Android Studio中目錄的邏輯結構和系統中的文件夾結構是分離的,依靠的就是Gradle的配置能力。對比標準的項目目錄結構,Cordova項目把android模塊直接放在了項目的根下,而不是其他模塊那樣(比如CordovaLib模塊)作為子文件夾存在,這也說明了它為什麼不需要項目的build.gradle腳本,因為項目的腳本就是android模塊的腳本。之後添加的模塊,都是作為根目錄的子文件夾存在的。
此外還有一個多出來的cordova.gradle,以及和G文名稱不一致的local.properties。
Gradle腳本的詳細說明
上面部分讓我們對用Android Studio打開的Cordova項目有了些感性了解。它有其自已的獨特性:一方面Cordova創建的項目有自己的Gradle配置腳本,另一方面又保留了自己獨特的結構。接下來讓我們對Gradle腳本的各個部分作較為詳細的了解,同樣的基礎知識請參考G文或《Gradle for Android》一書。
我們看到Gradle腳本相關的文件有build.gradle(CordovaLib模塊)、build.gradle(android模塊)、cordova.gradle(CordovaLib模塊)、settings.gradle(項目)、local.properties(SDK Location)。看起來有些不一樣。
不過沒關系,我們知道Gradle構建時首先要去找build.gradle腳本的。通過上面的項目結構知道,首先執行的應該是邏輯上屬於android模塊,但實際上位於項目根目錄下的build.gradle。就從這里開始。
android模塊的build.gradle腳本
打開build.gradle。首先看到一些Cordova生成的一些注釋。原文就不照抄了,大意是一些授權說明信息。最後的單行注釋很關鍵:"生成文件!請不要編輯!"。 雖然不能編輯,但一則其他的文件並沒有這么寫,二則做為入口文件,我們還是需要對它做一個了解。
注釋後緊接著就是buildscript方法。在它裡面首先是repositories方法,它告訴我們使用的庫是mavenCentral。接下來是依照已經在本地安裝的gradle的版本選擇使用的Gradle插件版本,並且語句上面有注釋可以參考,以後幾乎在每條語句上面都有注釋幫助我們理解並告訴我們相關參考資料的位置。
// 列表1-1。
buildscript {
repositories {
mavenCentral()
}
// Switch the Android Gradle plugin version requirement depending on the
// installed version of Gradle. This dependency is documented at
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
// and https://issues.apache.org/jira/browse/CB-8143
if (gradle.gradleVersion >= "2.2") {
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0+'
}
} else if (gradle.gradleVersion >= "2.1") {
dependencies {
classpath 'com.android.tools.build:gradle:0.14.0+'
}
} else {
dependencies {
classpath 'com.android.tools.build:gradle:0.12.0+'
}
}
}
隨後又使用了一個repositories任務。注釋說:允許插件通過build-extras.gradle聲明Maven依賴。通過extra這個名字,以及前面不要編輯的警告,它的作用可能是對這個build.gradle文件的修改或補充。其實在下面的代碼中可以看到更多這方面的信息。
// 列表1-2。
repositories {
mavenCentral()
}
接下來有一個wrapper任務,查閱文檔得知它用於定製Gradle Wrapper的。如果對Wrapper不了解,請參考《G》文的第一篇"使用Gradle Wrapper"部分。
// 列表1-3。
task wrapper(type: Wrapper) {
gradleVersion = '2.2.1'
}
接下來定義了一個ext屬性,其中定義了一些額外屬性。注釋也說明了其中定義的屬性需要通過環境變數、build-extras.gradle或gradle.properties設置。
ext屬性中首先引用了cordova.gradle。這樣就知道項目中這個文件用在哪裡了。但下面並沒有用到它。通過後面的代碼推測它可能是供build-extras.gradle調用的。接下來一系列條件判斷語句分別定義了一些屬性並把它們初為null。這些屬性是都以cdv開頭,表示一些Cordova構建屬性。接下來的代碼中會看到它們的作用。最後定義了一個cdvPluginPostBuildExtras數組變數,用來向裡面追加Gradle插件擴展。
// 列表1-4。
ext {
apply from: 'CordovaLib/cordova.gradle'
// The value for android.compileSdkVersion.
if (!project.hasProperty('cdvCompileSdkVersion')) {
cdvCompileSdkVersion = null;
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = null;
}
// Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null
}
// Sets the minSdkVersion to the given value.
if (!project.hasProperty('cdvMinSdkVersion')) {
cdvMinSdkVersion = null
}
// Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = null
}
// .properties files to use for release signing.
if (!project.hasProperty('')) {
= null
}
// .properties files to use for debug signing.
if (!project.hasProperty('cdvDebugSigningPropertiesFile')) {
cdvDebugSigningPropertiesFile = null
}
// Set by build.js script.
if (!project.hasProperty('cdvBuildArch')) {
cdvBuildArch = null
}
// Plugin gradle extensions can append to this to have code run at the end.
cdvPluginPostBuildExtras = []
}
接下來這部分代碼,首先判斷build-extras.gradle文件是否存在,如果存在則把它應用到構建腳本中。下面的判斷語句檢查build-extras.gradle是否定義了列表1-4的屬性。如果有就使用build-extras.gradle中的,如果沒有,則按下面語句設置:
// 列表1-5。
// Set property defaults after extension .gradle files.
if (ext.cdvCompileSdkVersion == null) {
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
}
if (ext.cdvBuildToolsVersion == null) {
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
}
if (ext.cdvDebugSigningPropertiesFile == null && file('debug-signing.properties').exists()) {
ext.cdvDebugSigningPropertiesFile = 'debug-signing.properties'
}
if (ext. == null && file('release-signing.properties').exists()) {
ext. = 'release-signing.properties'
}
// Cast to appropriate types.
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
上述代碼表示如果沒有設置列表1-4中的屬性時設置它們,其中調用了cordova.gradle腳本中的方法。如前所述之後會說明這些變數的作用。
接下來這段代碼,注釋告訴我們,要讓cdvBuild的任務依賴於debug/arch-specific,即平台相關,解決的是不同平台構建的問題。首先分成debug和release版,然後根據前面遇到過的cdvBuildMultipleApks和cdvBuildArch的變數判斷是否是跨平台構建,如果是則返回一個根據架構名生成的結果。注意到這個cdvBuildArch變數,在上面列表1-4的注釋中標明它由build.js設置。這個腳本位於項目目錄的cordova/lib/文件夾中,沒有納入到構建中,是cordova cli構建腳本,在這里先不做探討。
def computeBuildTargetName(debugBuild) {
def ret = 'assemble'
if (cdvBuildMultipleApks && cdvBuildArch) {
def arch = cdvBuildArch == 'arm' ? 'armv7' : cdvBuildArch
ret += '' + arch.toUpperCase().charAt(0) + arch.substring(1);
}
return ret + (debugBuild ? 'Debug' : 'Release')
}
// Make cdvBuild a task that depends on the debug/arch-sepecific task.
task cdvBuildDebug
cdvBuildDebug.dependsOn {
return computeBuildTargetName(true)
}
task cdvBuildRelease
cdvBuildRelease.dependsOn {
return computeBuildTargetName(false)
}
接下來定義了一個任務,顯然作用是輸出列表1-4以及後面定義過的屬性值。
task cdvPrintProps << {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode)
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
println('=' + )
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
println('cdvBuildArch=' + cdvBuildArch)
println('computedVersionCode=' + android.defaultConfig.versionCode)
android.proctFlavors.each { flavor ->
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
}
}
接下來就是構建的核心部分,每個使用android插件構建都會有的android方法。裡面對android的構建定義了一些配置。這些配置的做用可以參考相關文章,這里就不贅述了。之後是在任務准備就緒後,對需要驗證的任務進行驗證。再下來定義的addSigningProps函數被android方法調用,用來在需要驗證時,為屬性文件添加驗證配置。最後配置了構建後要執行的方法,並且添加了在自定義配置文件build-extras.gradle中配置的構建後執行方法的入口。
總結
綜上,在Cordova項目中的android文件夾中的默認兩個模塊的內容作為容器和插件的源代碼,有其相對於普通Gradle Android特殊的目錄結構。android模塊把CordovaLib和web內容結合在一起生成Crodova應用,android模塊和CordovaLib通過使用共同的配置變數,保證了包括編譯SDK版本在內的一致性,並提供了額外配置的入口。但萬變不離其宗,這一切都是建立在了解Gradle構建工具的基礎上的。
望採納,謝謝
㈤ APK的基本結構
APK(Android application package)代表Android應用程序包,是Android系統中的一種文件格式,用於打包Android應用程序。APK文件包含應用程序的所有文件,如靜態資源文件(assets)、庫文件(lib)、簽名文件(META-INF)、編譯資源文件(res)、配置清單文件(AndroidManifest.xml)、核心代碼文件(classes.dex)和資源映射文件(resources.arsc)等,APK文件的基本結構示例見圖1。通常,可以從應用市場或網站下載APK文件,然後使用Android系統提供的安裝器安裝應用程序。本文通過解壓某APK文件後的文件夾介紹這些文件資源的作用。
靜態資源文件主要指存放在assets文件夾中的文件。assets文件夾是一種未經編譯的資源目錄,它會被打包進APK文件中,在安裝應用程序後可以被訪問。assets文件夾中的文件不會被解壓縮,這意味著它們的訪問速度會比較快,但會佔用更多的安裝包空間。通常情況下,開發者會將應用程序中的靜態文件、配置文件、原始數據或其他不常改變的文件放在assets文件夾中。這樣可以使得應用程序的下載包大小變小,並且可以更快速地訪問這些文件。如圖2所示,在靜態資源assets文件夾中,可能存放一些圖片包括(jpg、png、gif等),還有可能存放js文件。
庫文件主要指lib文件夾中的文件,在這個文件夾中,存放了運行APP所需要的so文件,也就是動態鏈接庫的二進制文件。為了適配不同安卓系統處理器的版本,lib文件夾中的so庫也是按不同處理器版本的文件夾分類放置。在圖3的示例中,分成了三種文件夾包括armeabi、armeabi-v7a和x86文件夾,分別用來存儲適配arm5架構、arm7架構、Intel32架構的CPU處理器版本的安卓系統。例如,如果智能手機使用的是arm7架構CPU處理器版本的安卓系統,APP在運行時就會調用armeabi-v7a文件夾下的動態鏈接庫文件執行程序。
簽名文件指的是存放在META-INF文件夾中的文件。META-INF文件夾是Android系統中的一種特殊文件夾,它用來存放應用程序的簽名信息。在META-INF文件夾中可以找到三種常見的文件:CERT.RSA、CERT.SF和MANIFEST.MF,META-INF文件夾示例見圖5。CERT.RSA、CERT.SF這兩個文件用來存放應用程序的簽名信息。當安裝一個應用程序時,Android系統會檢查這兩個文件,以確保應用程序的完整性和安全性。MANIFEST.MF文件用來存放應用程序的所有文件的清單信息。
編譯資源文件主要指存放在res文件夾中的文件。res文件夾,存放的也是資源文件,與assets文件夾不同的是,這里是編譯後的資源文件。直接打開可能顯示亂碼。在res文件夾中你會找到許多子文件夾,每個子文件夾都用來存放特定類型的資源文件,res文件夾示例見圖6。主要的文件夾包括drawable文件夾、layout文件夾和values文件夾。
AndroidManifest.xml文件是配置清單文件,也是編譯過的文件,用來描述應用程序的清單信息。包括包名、應用名、許可權、安卓四大組件、版本等重要信息都在這裡面聲名。
核心代碼文件主要指classes.dex文件。classes.dex文件是Android系統中重要的代碼文件,它是Dalvik可執行文件的縮寫。Dalvik是Android系統中的一種虛擬機,它負責在Android系統中運行應用程序的代碼。classes.dex文件運行在Dalvik虛擬機上的核心代碼文件,它反編譯後的語言是smali代碼語言,smali代碼可轉換為java代碼。對於大的APK文件會出現多個dex文件,但在APP實際運行的過程中會將多個dex文件合並成一個dex文件運行。APK打包時存放多個dex的原因是每個dex文件的大小是有限制的。
resources.arsc文件是Android系統中的一種特殊文件,它用來存放應用程序的資源表。資源表是一種二進制文件,它包含了應用程序的資源ID和資源類型的映射關系。