Android核心庫

風靈使發表於2018-11-06
  • 什麼是Android核心庫
  • Android核心庫包括哪幾部分,有哪些功能?
  • Android系統API如何實現?
  • ApiCheck機制的原理
  • 如何使用Android系統自帶資源包?

Android執行庫分為兩個部分,分別是Dalvik虛擬機器和核心庫(Corelibraries)。核心庫主要用於提供基本的Java類庫的功能,另外,Android官方提供Java語言供應用開發者開發應用。因此,Android向上提供了Android應用框架層,而該框架層則需要Android系統API來提供介面。

Android核心庫簡介

Android應用程式使用Java語言編寫,其大部分Java語言基礎功能都由Android核心庫提供,比如基礎資料結構、數學、I/O、工具、資料庫、網路等庫。其中大部分實現來源於ApacheHarmony專案,核心庫的具體實現位於libcore目錄中,Java部分最終會被打包為core.jar包,經過安裝,最終將被放置在目標檔案系統的system\framework\目錄中,當桌面啟動時首先載入,作為Java程式的一個基礎包。

libcore中的C/C++程式碼被編譯為libjavacore.a在這裡插入程式碼片靜態庫,是Java核心庫的原生程式碼。

另外,libcore目錄中還包括部分測試用例,用來測試Java核心庫的基本介面功能實現,在移植Android或者其虛擬機器時,也可以使用它們來測試Java核心庫的功能。

核心庫主要實現了以下Java基礎包:

  • Java標準API(java包)
  • Java擴充套件API(javax包)
  • 企業和組織提供的Java類庫(org包)

注意:Android核心庫雖然實現了Java標準部分的大部分內容,但也有部分API沒有被支援,比如GUI系統的Swing等。

Android系統API

Android系統API是基於Android核心庫實現的Android系統應用框架層的API,即Android系統構架圖中從上開始的第二層,也就是應用開發人員所使用的android包。Android的每個包都以android開頭。

Android包

android包主要負責向Android應用程式開發人員提供可用的API,其實現位於”framework\base\”目錄中,其中”framework\base\core\java”包含了大部分API,還有另外一部分API屬於Android系統庫中的擴充套件庫部分,分別位於:

-framework\base\graphics\java\

-framework\base\media\java\

-framework\base\opengl\java\

-framework\base\wifi\java\

-framework\base\location\java\

…

可以看出,其目錄和程式碼的組織形式都比較類似,各個子目錄和檔案是根據java包的關係來組織的-資料夾的層次結構表示包和子包,檔名稱和Java類的名稱一致。比如:android\app\Activity.java對應android.app.activity類。android包的具體實現會通過JNI呼叫本地C++程式碼。

Android資源包

android包中除了系統API之外,還包括了部分資原始檔,比如圖片、多國語言字串、佈局檔案等,它們被統一放置在”framework\base\core\res\”目錄中,最終會被編譯為framework-res.apk包,放置在目標檔案系統的”system\framework\”目錄中。

ApiCheck機制

android提供了一個ApiCheck工具,用來驗證經過編譯生成的SDK的API是否符合標準,即ApiCheck機制。Android對於所有的類和API都分為開放式和不開放式兩種,開放式是可供SDK使用的API,反之則為不開放式,也就是我們在原始碼中看到的加/**} */註解的API,它們都不能被使用。

為了最大限度地保持Android系統的相容性,ApiCheck機制要求Android程式碼中所有的API都必須和API描述檔案一致,這裡所說的描述檔案是位於“framework\base\api\”目錄中的.xml檔案。

開啟其中主要的檔案current.xml可以看到整個檔案的內容都包括在<api>...</api>標籤之間,作為Android的系統API。其中還包含一些其他的標籤,如下表所示
在這裡插入圖片描述

由於數量較多,表中只列舉 一些常用的,下面我們 通過一段API實現程式碼來分析這些標籤的使用,程式碼清單如下所示為android.app.activity類實現。

Android.app.activity片段

public class Activity extendsContextThemeWrapper implements LayoutInflater.Factory,Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener,ComponentCallbacks {

private static final String TAG =“Activity”;

private static final classManagedCursor {

ManagedCursor(Cursor cursor) {

mCursor = cursor;

mReleased = false;

mUpdated = false;

}

private final Cursor mCursor;

private boolean mReleased;

private boolean mUpdated;

}

public Activity() {

++sInstanceCount;

}

protected void finalize() throwsThrowable {

super.finalize();

--sInstanceCount;

}

protected void onCreate(BundlesavedInstanceState) {

mVisibleFromClient=!mWindow.getWindowStyle().getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay,false);

mCalled = true;

}

protected void onPause() {

mCalled = true;

}

//省略部分...

}

Activity類對應在API描述檔案中的內容程式碼清單如下:

activity類的API描述片段

<class name="Activity" extends="android.view.ContextThemeWrapper" abstract="false" static="false" final="false" deprecated="not deprecated" visibility="public"> 
  <implements name="android.content.ComponentCallbacks"/>  
  <implements name="android.view.KeyEvent.Callback"/>  
  <implements name="android.view.LayoutInflater.Factory"/>  
  <implements name="android.view.View.OnCreateContextMenuListener"/>  
  <implements name="android.view.Window.Callback"/>  
  <constructor name="Activity" type="android.app.Activity" static="false" final="false" deprecated="not deprecated" visibility="public"></constructor>  
  <method name="finish" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public"></method> 
  <! 省略部分...>
</class>

class標籤表明類名是Activity,其中的extends值表示繼承自“android.view.ContextThemeWrapper”類;幾個implements標籤表明需要實現的一些介面,如android.content.ComponentCallbacks等;constructor標籤說明建構函式為Activity,型別為android.app.Activity;另外,method標籤描述了方法finish及其相關屬性。由於篇幅關係,這裡不一一介紹每一個標籤的功能,該描述檔案將在執行makeupdate-api命令時自動生成,但是也需要我們指定被包含的API的路徑。這種情況通常用於:當我們加入新的API到Android系統中,如果只使用makeupdate-api命令則無效,需要在build\core\pathmap.mk中將自定義的新API加入進去,再使用更新命令才能生成,如果在一個已有的包中加入新的API,則不需要指定路徑,直接使用更新命令即可。

所有的Android系統API和Java標準介面都對應於AndroidSDK中的android.jar檔案。

擴充套件學習

當然,如果不需要使用Android的ApiCheck機制,可以在build\core\tasks\apicheck.mk中將其關閉,只需要註釋掉”$(hide)( $(APICHECK) $(4) $(2) $(3) || ($(5); exit38))”即可(如果沒有修改過該檔案,則位於35行)。注意:這樣做可能會引起相容性問題。

小結

主要介紹了Android的核心庫和系統API實現,它們都離不開JNI機制。通過JNI機制可以把底層的C/C++介面暴露給上層的java應用程式框架層,從而使用Android上層可以使用java語言來開發應用程式。各個部分都會存在JNI介面,用來將自身的功能提供給上層的java程式。經過這樣依次轉換,雖然能夠實現跨語言,但是效率難免會受到一定的影響,所以Android官方推出了NDK,使應用開發人員能夠直接使用C++語言來編寫應用程式。

相關文章