天天看點

Android系統架構Android系統架構Android 層間調用JNI(Java Native Interface)NDK

Android系統架構

Android系統架構Android系統架構Android 層間調用JNI(Java Native Interface)NDK

(一)Linux Kernel(/kernel,/bootable,/devices)

Android核心 對Linux核心進行了增強,增加了一些面向移動計算的特有功能。例如:

  • 低記憶體管理器LMK(Low Memory Keller)。源代碼位于 drivers/staging/ android/lowmemorykiller.c
  • 匿名共享記憶體(Ashmem),mm/ashmem.c。
  • 輕量級的程序間通信Binder機制,源代碼位于drivers/staging/android/binder.c。等。

這些核心的增強使Android在繼承Linux核心安全機制的同時,進一步提升了記憶體管理,程序間通信等方面的安全性。

Android Linux Kernel 特征:

1.它沒有glibc支援

由于Android最初用于一些便攜的移動裝置上,是以,可能出于效率等方面的考慮,Android并沒有采用glibc作為

C庫,而是Google自己開發了一套Bionic Libc來代替glibc。

2.它并不包括一整套标準的Linux使用程式

Android并沒有完全照搬Liunx系統的核心,除了修正部分Liunx的Bug之外,還增加了不少内容,比如:它基于ARM

構架增加的Gold-Fish平台,以及yaffs2 FLASH檔案系統(如果學習了嵌入式的話就會知道yaffs2 FLASH檔案系

統已經在基于linux的很多嵌入式裝置上采用了,技術已經非常成熟)等。

3.它沒有本地基于X服務的視窗系統

什麼是本地視窗系統呢?本地視窗系統是指GNU/Linux上的X視窗系統,或者Mac OX X的Quartz等。不同的作業系統

的視窗系統可能不一樣,Android并沒有使用(也不需要使用)Linux的X視窗系統(對原作者的這個觀點不是很贊

同,原文章這一點放在第一條,并說“這是Android不是Linux的一個基本原因”,這個不敢苟同,由于作者 沒有

指明android用的什麼顯示系統,我也不好說)。

4.Android專有的驅動程式

除了上面這些不同點之外,Android還對Linux裝置驅動進行了增強,主要如下所示。

1)Android Binder 基于OpenBinder架構的一個驅動,用于提供 Android平台的程序間通信(InterProcess

Communication,IPC)功能。源代碼位于drivers/staging/android/binder.c。

2)Android電源管理(PM) 一個基于标準Linux電源管理系統的輕量級Android電源管理驅動,針對嵌入式裝置做

了很多優化。源代碼位于:

kernel/power/earlysuspend.c

kernel/power/consoleearlysuspend.c

kernel/power/fbearlysuspend.c

kernel/power/wakelock.c

kernel/power/userwakelock.c

3)低記憶體管理器(Low Memory Killer) 比Linux的标準的OOM(Out Of Memory)機制更加靈活,它可以根據需要

殺死程序以釋放需要的記憶體。源代碼位于 drivers/staging/ android/lowmemorykiller.c。

4)匿名共享記憶體(Ashmem) 為程序間提供大塊共享記憶體,同時為核心提供回收和管理這個記憶體的機制。源代碼位于

mm/ashmem.c。

5)Android PMEM(Physical) PMEM用于向使用者空間提供連續的實體記憶體區域,DSP和某些裝置隻能工作在連續的物

理記憶體上。源代碼位于drivers/misc/pmem.c。

6)Android Logger 一個輕量級的日志裝置,用于抓取Android系統的各種日志。源代碼位于

drivers/staging/android/logger.c。

7)Android Alarm 提供了一個定時器,用于把裝置從睡眠狀态喚醒,同時它還提供了一個即使在裝置睡眠時也會

運作的時鐘基準。源代碼位于drivers/rtc/alarm.c。

8)USB Gadget驅動 一個基于标準 Linux USB gadget驅動架構的裝置驅動,Android的USB驅動是基于gaeget框

架的。源代碼位于drivers/usb/gadget/。

9)Android Ram Console 為了提供調試功能,Android允許将調試日志資訊寫入一個被稱為RAM Console的裝置

裡,它是一個基于RAM的Buffer。源代碼位于drivers/staging/android / ram_console.c。

10)Android timed device 提供了對裝置進行定時控制的功能,目前支援vibrator和LED裝置。源代碼位于

drivers/staging/android /timed_output.c(timed_gpio.c)。

11)Yaffs2 檔案系統 Android采用Yaffs2作為MTD nand flash檔案系統,源代碼位于fs/yaffs2/目錄下。

Yaffs2是一個快速穩定的應用于NAND和NOR Flash的跨平台的嵌入式裝置檔案系統,同其他Flash檔案系統相比,

Yaffs2能使用更小的記憶體來儲存其運作狀态,是以它占用記憶體小。Yaffs2的垃圾回收非常簡單而且快速,是以能表

現出更好的性能。Yaffs2在大容量的NAND Flash上的性能表現尤為突出,非常适合大容量的Flash存儲。

(二)硬體抽象層HAL(/hardware)

Android系統架構Android系統架構Android 層間調用JNI(Java Native Interface)NDK
  • 對下:對linux核心驅動程式封裝,這樣,對硬體的操作分成兩層,抽象層位于使用者空間,驅動程式位于核心。為了避免硬體資訊的公開,隻開源驅動層的代碼即可。
  • 對上:對上層應用提供一個統一的簡單的查詢硬體裝置的接口。它所謂的抽象,基本上也就僅限于這一功能,它通常并不提供對硬體的實際操作,對硬體的操作,還是由應用程式來完成。

Linux核心源代碼版權遵循GNU License,而android源代碼版權遵循Apache License,前者在釋出産品時,必須公布源代碼,而後者無須釋出源代碼。如果把對硬體支援的所有代碼都放在Linux驅動層,那就意味着釋出時要公開驅動程式的源代碼,而公開源代碼就意味着把硬體的相關參數和實作都公開了,核心驅動層隻提供簡單的通路硬體邏輯,例如讀寫硬體寄存器的通道,至于從硬體中讀到了什麼值或者寫了什麼值到硬體中的邏輯,都放在硬體抽象層中去了,

(三)系統運作時庫(/libcore,/dalvik,/bionic,/system)

  • 程式庫:C/C++庫,這些庫能被Android系統中不同的元件使用。

    它們通過Android Framework為開發者提供服務。

  • 運作庫:

    Core Libraries 提供了JAVA程式設計語言核心庫的大多數功能,API,會調用native方法, android.os,android.NET,android.media

    Dalvik虛拟機 每一個 Android應用程式都在它自己的程序中運作,都擁有一個獨立的Dalvik虛拟機執行個體。

(四)Android 應用程式架構(/framework)

應用程式架構層是我們從事Android開發的基礎,很多核心應用程式也是通過這一層來實作其核心功能的,該層簡化了元件的重用,開發人員可以直接使用其提供的元件來進行快速的應用程式開發,也可以通過繼承而實作個性化的拓展。

(五)Android 應用程式(/packages)

包括各類與使用者直接互動的應用程式,或由java語言編寫的運作于背景的服務程式,例如,智能手機上實作的常見基本功能 程式,諸如SMS短信,電話撥号,圖檔浏覽器,月曆,遊戲,地圖,web浏覽器等程式,以及開發人員開發的其他應用程式。

Android 層間調用

Android系統架構Android系統架構Android 層間調用JNI(Java Native Interface)NDK

以Audio為例:(應用程式調用硬體裝置)

應用程式調用了應用架構層的Runtime Service(這裡是MediaPlayer),然後通過JNI調用與之綁定的Runtime Library (這裡是MediaPlayer)。這時MediaPlayer又分别調用MediaFramework,和通過Binder IPC 的方式調用AudioFlinger(原生服務),而後通過AudioFlinger調用指定的庫(libaudio.so),最後才調用Kernel Driver 。

JNI(Java Native Interface)

它提供了若幹的API實作了Java和其他語言的通信(主要是C&C++)

上層Java(Framework)要調用底層的C/C++函數庫(Libraries)必須通過Java的JNI來實作。

Java通過JNI機制和C/C++溝通的具體步驟

1、編寫包含native本地方法的java類(.java)

2、通過javah工具生成C/C++語言的頭檔案(.h)

3、使用C/C++語言實作頭檔案(.c)

4、使用交叉編譯工具對C/C++本地代碼進行編譯,最後通過連結生成*.so可執行的C/C++庫(.so)

5、實際執行Java代碼去和本地的C/C++代碼互相溝通

NDK

NDK是Google公司推出的幫助Android開發者通過C/C++本地語言編寫應用的開發包,包含了C/C++的頭檔案、庫檔案、說明文檔和示例代碼,我們可以了解為Windows Platform SDK一樣,是純C/C++編寫的,但是Android并不支援純C/C++編寫的應用,同時NDK提供的庫和函數功能很有限,僅僅處理些算法效率敏感的問題

簡單點說,用C語言生成一個庫檔案,在java中調用這個庫檔案的函數。JNI的過程比較複雜,生成.so需要大量操作,而NDK就是簡化了這個過程。
Android系統架構Android系統架構Android 層間調用JNI(Java Native Interface)NDK
Android系統架構Android系統架構Android 層間調用JNI(Java Native Interface)NDK