㈠ 驅動開發需要學什麼
驅動開發需要學的如下:
一、android驅動的基礎知識
1、Android驅動是基於linux驅動,強烈推薦閱讀Linux Device Driver3rd版,這本書講了Linux下設宴遊伍備驅動的基礎知識,要求反復細讀。
2、能讀懂和編寫一些C程序晌或。
3、能懂java基礎,因為Framework層的代磨敬碼與驅動代碼聯系比較緊密,稍懂一些Java代碼,會發現對整個驅動框架的了解更加熟悉。
四、熱愛驅動開發和不斷學習
做Android驅動開發需要的是不斷的學習,時刻保持著一股激情,不斷的學習才能更好的完成日常的驅動開發任務,並能保持對開發的敏銳感覺。
㈡ Android 驅動開發應該如何入門和學習成長
一.認識android的架構
Android其本質就是在標準的Linux系統上增加了Java虛擬機Dalvik,並在Dalvik虛擬機上搭建了一個JAVA的application framework,所有的應用程序都是基於JAVA的application framework之上。
android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。
二.搭建環境
搭建開發環境
對國內的開發者來說最痛苦的是無法去訪問android開發網站。為了更好的認識世界,對程序員來說,會翻牆也是的一門技術,帶你去領略牆外的世界,好了,不廢話了, 國內開發者訪問(androiddevtools) 上面已經有了所有你要的資源,同時可以下載到我們的主角framework
但是這樣的搭建只能去閱讀源代碼,我們無法去更進一步去實現自己的rom,我們看到錘子的系統在早期的開放rom是自己從新實現了framework的代碼,現在看起來他成功了,所以我們還要去搭建android系統的源碼編譯環境。
搭建源碼編譯環境
三.開始主題
在一開始寫c程序的時候都有一個運行的入口,比如
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
//這里的main就是應用的入口
int main(int argc, const char * argv[]){
return 0;
}
在計算機網路原理中我們用socket實現一個伺服器端,不斷的接聽客戶端的訪問,而且他的代碼是這樣實現的:
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
#include <stdio.h>
void main()
{
WORD wVersionRequested;//版本號
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//載入套接字型檔,如果失敗返回
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return;
}
//判斷高低位元組是不是2,如果不是2.2的版本則退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//創建流式套接字,基於TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址結構體的創建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//轉換Unsigned long型為網路位元組序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定埠號,除sin_family參數外,其它參數都是網路位元組序,因此需要轉換
//將套接字綁定到一個埠號和本地地址上
bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必須用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字義用來接收客戶端Socket的結構體
int len = sizeof(SOCKADDR);//初始化參數,這個參數必須進行初始化,sizeof
//循環等待接受客戶端發送請求
while (1)
{
//等待客戶請求到來;當請求到來後,接受連接請求,
//返回一個新的對應於此次連接的套接字(accept)。
//此時程序在此發生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化輸出
//用返回的套接字和客戶端進行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多發送一個位元組
//接收數據
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他採用了一個while死循環去監聽客戶端的請求。
先上源代碼
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
//從中可以看到為app開辟了一個線程進入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源碼失望了,沒有一個while循環啊,其實用了他方法實現
//用一個looper的機制循環監聽響應
Looper.prepareMainLooper();
Looper.loop();
進一步深入代碼
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在這里看到了一個循環監聽消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that ring the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
㈢ android的系統結構
Android 是運行於Linux kernel之上,但並不是GNU/Linux。因為在一般GNU/Linux 里支持的功能,Android 大都沒有支持,包括Cairo、X11、Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。Android又以Bionic 取代Glibc、以謹段Skia 取代Cairo、再以opencore取代FFmpeg等等。Android 為了達到商業應用,必須移除被GNU GPL授權證所約束的部份,例如Android將驅動程序移到 Userspace,使得Linux driver 與 Linux kernel徹底分開。Bionic/Libc/Kernel/ 並非標準的Kernel header files。Android 的 Kernel header 是利用工具由 Linux Kernel header 所產生的,這樣做是為了保留常數、數據結構與宏。
Android 的 Linux kernel控制包括安全(Security),存儲器管理(Memory Management),程序管理(Process Management),網路堆棧(Network Stack),驅動程序模型(Driver Model)等。下載Android源碼之前,先要安裝其構建工具 Repo來初始化源碼。Repo 是 Android 用來輔助Git工作的一個工具。 APK是安卓應用的後綴,是AndroidPackage的縮寫,即Android安裝包祥陵譽(apk)。APK是類似Symbian Sis或Sisx的文件格式。通過將APK文件直接傳到Android模擬器或Android手機中執行即可安裝。apk文件和sis一樣,把android sdk編譯的工程打包成一個安裝程序文件,格式為apk。 APK文件其實是zip格式,但後綴名被修改為apk,通過UnZip解壓後,可以看到Dex文件,Dex是Dalvik VM executes的全稱,即Android Dalvik執行程序,並非Java ME的位元組碼而是Dalvik位元組碼。
APK文件結構
一個APK文件結構為:
1. META-INF (註:Jar文件中常可以看到);
2. res (註:存放資源文件的目錄) ;
3. AndroidManifest.xml (註:程序全局配置文件) ;
4. classes.dex (註:Dalvik位元組碼);
5. resources.arsc (註:編譯後的二進制資源文件)。
總結下我們發現Android在運行一個程序時首先需要UnZip,然後類似Symbian那樣直接執行安裝,和Windows Mobile中的PE文件有區別,這樣做對於程序的保密性和可靠性不是很高,通過dexmp命令可以反編譯,但這樣做符合發展規律,微軟的 Windows Gadgets或者說WPF也採用了這種構架方式。
在Android平台中dalvik vm的執行文件被打包為apk格式,最終運行時載入器會解壓然後獲取編譯後androidmanifest.xml文件中的permission分支相關的安全訪問,但仍然存在很多安全限制,如果你將apk文件傳到/system/app文件夾下會發現執行是不受限制的。
最終我們平時安裝的文件可能不是這個文件夾,而在android rom中系統的apk文件默認會放入這個文件夾,它們擁有著root許可權。 Android 的HAL(硬體抽像層)是能以封閉源碼形式提供硬體驅動模塊。HAL 的目的是為了把 Android framework 與 Linux kernel 隔開,讓 Android 不至過度依賴 Linux kernel,以達成 Kernel independent 的概念汪塌,也讓 Android framework 的開發能在不考量驅動程序實現的前提下進行發展。
HAL stub 是一種代理人(Proxy)的概念,Stub 是以 *.so 檔的形式存在。Stub 向 HAL「提供」操作函數(Operations),並由 Android runtime 向 HAL 取得 Stub 的Operations,再 Callback 這些操作函數。HAL 里包含了許多的 Stub(代理人)。Runtime 只要說明「類型」,即 Mole ID,就可以取得操作函數。 操作系統與應用程序的溝通橋梁,應用分為兩層:函數層(Library)和虛擬機(Virtual Machine)。 Bionic是 Android 改良libc的版本。Android 同時包含了Webkit,所謂的Webkit 就是Apple Safari 瀏覽器背後的引擎。Surface flinger 是就2D或3D的內容顯示到屏幕上。Android使用工具鏈(Toolchain)為Google自製的Bionic Libc。
Android採用OpenCORE作為基礎多媒體框架。Open CORE可分7大塊:PVPlayer、PVAuthor、Codec、PacketVideo Multimedia Framework(PVMF)、Operating System Compatibility Library(OSCL)、Common、OpenMAX。
Android 使用skia 為核心圖形引擎,搭配OpenGL/ES。skia與Linux Cairo功能相當,但相較於Linux Cairo, skia 功能還只是雛形的。2005年Skia公司被Google收購,2007年初,Skia GL源碼被公開,Skia 也是Google Chrome 的圖形引擎。
Android的多媒體資料庫採用SQLite資料庫系統。資料庫又分為共用資料庫及私用資料庫。用戶可通過ContentResolver類(Column)取得共用資料庫。
Android的中間層多以Java 實現,並且採用特殊的Dalvik 虛擬機(Dalvik Virtual Machine)。Dalvik虛擬機是一種「暫存器型態」(Register Based)的Java虛擬機,變數皆存放於暫存器中,虛擬機的指令相對減少。
Dalvik虛擬機可以有多個實例(Instance), 每個Android應用程序都用一個自屬的Dalvik虛擬機來運行,讓系統在運行程序時可達到優化。Dalvik 虛擬機並非運行Java位元組碼(Bytecode),而是運行一種稱為.dex格式的文件。 Android本身是一個許可權分立的操作系統。在這類操作系統中,每個應用都以唯一的一個系統識別身份運行(Linux用戶ID與群組ID)。系統的各部分也分別使用各自獨立的識別方式。Linux就是這樣將應用與應用,應用與系統隔離開。
系統更多的安全功能通過許可權機制提供。許可權可以限制某個特定進程的特定操作,也可以限制每個URI許可權對特定數據段的訪問。
Android安全架構的核心設計思想是,在默認設置下,所有應用都沒有許可權對其他應用、系統或用戶進行較大影響的操作。這其中包括讀寫用戶隱私數據(聯系人或電子郵件),讀寫其他應用文件,訪問網路或阻止設備待機等。
安裝應用時,在檢查程序簽名提及的許可權,且經過用戶確認後,軟體包安裝器會給予應用許可權。從用戶角度看,一款Android應用通常會要求如下的許可權:
撥打電話、發送簡訊或彩信、修改/刪除SD卡上的內容、讀取聯系人的信息、讀取日程信的息,寫入日程數據、讀取電話狀態或識別碼、精確的(基於GPS)地理位置、模糊的(基於網路獲取)地理位置、創建藍牙連接、對互聯網的完全訪問、查看網路狀態,查看WiFi狀態、避免手機待機、修改系統全局設置、讀取同步設定、開機自啟動、重啟其他應用、終止運行中的應用、設定偏好應用、震動控制、拍攝圖片等。
一款應用應該根據自身提供的功能,要求合理的許可權。用戶也可以分析一款應用所需許可權,從而簡單判定這款應用是否安全。如一款應用是不帶廣告的單機版,也沒有任何附加的內容需要下載,那麼它要求訪問網路的許可權就比較可疑。
㈣ 做Android驅動開發一定要懂Framework嗎
理論上是不太需要。不過作為一個android開發者,任何一個方面都需要了解,這樣可以開發出更健壯的程序。驅動大部分是c,c++的。framework在驅動上層,將驅動功能封裝為到java層給應用提供出系統硬體服務
㈤ Android的硬體抽象層和驅動體系為什麼這么弱暴
在各個廠商開發基於Android系統的產品的時候,雖然有的時候也需要修改Android的框架,但是移植是其中的主要工作。 Android系統本身是一個龐大的系統,移植並不需要精通Android的每一個部分,需要考慮的是Android系統的硬體抽象層(HAL)和Linux中的相關設備驅動程序。如圖1-3所示。 圖1-3 Android移植的概念 基於Android系統的手機,包括G1、G2、Hero和Nexus One,其他的手機廠商也推出了幾款Android手機。這些手機所使用的處理器和各種外圍硬體各不相同,但是其使用的大部分Android系統的軟體都是相同的(包括本地框架、虛擬機、Java框架和Java應用等部分)。 移植的目的就是為了改動較小的內容,支撐較為龐大上層的系統。同時由於硬體抽象層具有標準的介面,在各個不同的平台的實現中可以互相參考,雖然具體實現的內容不同,但是思路類似,可以相互參考。 Android系統的移植工作的目的是為了在特定的硬體上運行Android系統。在移植的過程中,把握關鍵要點,減少工作量是一個重要的方面。從工作的角度,通常的方法為,首先要熟悉硬體抽象層的介面,其次要集成和復用已有的驅動程序,主要的工作量在硬體抽象層的實現中。為了更好地理解和調試系統,也應該適當地了解上層對硬體抽象層的調用情況。 移植方面主要的工作有兩個部分: Linux驅動 Android系統硬體抽象層 Linux中的驅動工作在內核空間,Android系統硬體抽象層工作在用戶空間,有了這兩個部分的結合,就可以讓龐大的Android系統運行在特定的硬體平台上。 Android移植的主要工作如圖1-4所示。 圖1-4 Android移植的主要工作 在具有了特定的硬體系統之後,通常在Linux中需要實現其驅動程序,這些驅動程序通常是Linux的標准驅動程序,在Android平台和其他Linux平台基本上是相同的。主要的實現方面是Android系統中的硬體抽象層(Hardware Abstract Layer),硬體抽象層對下調用Linux中的驅動程序,對上提供介面,以供Android系統的其他部分(通常為Android本地框架層)調用。 提示:Android硬體抽象層的介面是本地移植層的介面,不屬於標准API,不具有向前或者向後兼容性。 在Android系統需要移植的內容,主要包含了以下的各個部分: 顯示部分(Display) 包括framebuffer驅動+Gralloc模塊(可選擇是否實現) 用戶輸入部分(Input) 包括Event驅動+EventHub(Android標准內容) 多媒體編解碼(Codec) 包括硬體Codec驅動+Codec插件(如OpenMax) 3D加速器部分(3D Accelerator) 包括硬體OpenGL驅動+OpenGL插件 音頻部分(Audio) 包括Audio驅動+Audio硬體抽象層 視頻輸出部分(Video Out) 包括視頻顯示驅動+Overlay硬體抽象層 攝像頭部分(Camera) 包括Camera驅動(通常是v4l2)+Camera硬體抽象層 電話部分(Phone) Modem驅動程序+RIL庫 全球定位系統部分(GPS) 包括GPS驅動(通常為串口)+GPS硬體抽象層 無線區域網部分(WIFI) 包括Wlan驅動和協議+WIFI的適配層(Android標准內容) 藍牙部分(Blue Tooth) 包括BT驅動和協議+BT的適配層(Android標准內容) 感測器部分(Sensor) 包括Sensor驅動+Sensor硬體抽象層 震動器部分(Vibrator) 包括Vibrator驅動+Vibrator硬體抽象層(Android標准內容) 背光部分(Light) 包括Light驅動+ Light硬體抽象層 警告器部分(Alarm) 包括Alarm驅動和RTC系統+用戶空間調用(Android標准內容) 電池部分(Battery) 包括電池部分驅動+電池的硬體抽象層(Android標准內容) Android中具有很多組件,但並不是每一個部件都需要移植,對於一些純軟的組件,就沒有移植的必要。對於一些部件,例如瀏覽器引擎,雖然需要下層網路的支持,但是並非直接為其移植網路介面,而是通過無線區域網或者電話系統數據連接來完成標準的網路介面。 Android的移植主要可以分成幾個類型:基本圖形用戶界面(GUI)部分,包括顯示部分和用戶輸入部分;和硬體相關的加速部分,包括媒體編解碼和OpenGL;音視頻輸入輸出環節,包括音頻,視頻輸出和攝像頭部分;連接部分,包括無線區域網,藍牙,GPS;電話部分;附屬部件:包括感測器、背光、振動器等。 除了以上的移植方面,電源管理也是非常重要的一個方面,它和Android的各個子系統都有關系。 Android系統主要需要移植部件如圖1-5所示。 圖1-5 Android系統主要需要移植部件 對於大部分子系統,硬體抽象層和驅動程序都需要根據實際系統的情況實現,例如:感測器部分、音頻部分、視頻部分、攝像頭部分、電話部分。也有一些子系統,硬體抽象層是標準的,只需要實現Linux內核中的驅動程序即可,例如:輸入部分、振動器部分、無線區域網部分、藍牙部分等。對於有標準的硬體抽象層的系統,有的時候通常也需要做一些配置工作。 時至今日,隨著Android系統的發展,它已經不僅僅是一個移動設備的平台,也可以用於消費類電子和智能家電,例如:上網本、電子書、數字電視、機頂盒、固定電話等。在這些平台上,通常需要實現比移動設備更少的部件。一般來說,基本用戶界面部分(包括顯示和用戶輸入)是需要移植的,其他部分是可選的。例如:電話系統、振動器、背光、感測器等一般不需要在非移動設備系統來實現;對於一些固定位置設備通常也不需要實現GPS系統。 圖片無法顯示,見諒
㈥ android軟體開發的架構
Android以Java為編程語言,使介面到功能,都有層出不窮的變化,其中Activity等同於J2ME的MIDlet,一個 Activity 類(class)負責如世御創建視窗(window),一個活動中的Activity就是在 foreground(前景)模式,背景運行的程序叫做Service。兩者之間通過由和AIDL連結,達到復數程序同時運行的效果。如果運行中的 Activity 全部畫面被其他 Activity 取代時,該 Activity 便被停止(stopped),甚至被系統清除(kill)。
View等同於J2ME的Displayable,程序人員可以通過 View 類與「XML layout」檔將UI放置在視窗上,Android 1.5的版本可以利用 View 打造出所謂的 Widgets,其實Widget只是View的一種,所以可以使用xml來設計layout,HTC的Android Hero手機即含有大量的widget。至於ViewGroup 是各種layout 的基礎抽象類(abstract class),ViewGroup之內還可以有ViewGroup。View的構造函數不需要在Activity中調用,但是Displayable的是必須的,在Activity 中,要通過()來從XML 中取得View,Android的View類的顯示很大程度上是從XML中讀取的。View 與事件(event)息息相關,兩者之間通過Listener 結合在一起,每一個渣岩View都可以注冊一個event listener,例如:當View要處理用戶觸碰(touch)的事件時,就要向Android框架注冊View.。另外還有Image等同於J2ME的BitMap。 在模擬器上運行模擬是虛擬設備(AVD),我們需要配置來運行我們的Android應用程序。步驟1、開放的AVD管理步驟2、新的按鈕,點擊添加新設備,並配置您的設備設置。步驟3、會有一個結果窗口顯示所有已配置你上一屏幕選擇。步驟4、按「確定」,你將會看到你的設備列在有你可以關閉此窗口。步驟5、運行你的Android應用程序項目從Eclipse,如果只有一個AVD配置,它會自動部署的應用程序也會出現一個窗口,選擇你的圖片。 模擬器將開始。在設備上運行
Android應用程序可以直接部署在Android設備上,這幾個配置所需要的。步驟1、在調試模式的設置可以設置應用程序:Android的<應用程序>元真可調試屬性。ADT 8這是默認的。步驟2、您的設備上啟用USB調試:Android 3.2或以上轉至設置>應用程序>開發和啟用USB調試。在Android 4更新,這是開發商選擇設置>。註:在Android 4.2更新,開發者選項是默認隱藏。可以,去設定>android的版本號。返回先前屏幕找到開發商選擇。步返敗驟3、安裝USB驅動程序為您的設備,計算機識別你的設備。步驟4、一旦設置和您的設備通過USB連接,從Eclipse菜單欄安裝您的應用程序在設備上選擇運行>運行(或運行>調試)。 操作系統與應用程序的溝通橋梁,並用分為兩層:函數層(Library)和虛擬機(Virtual Machine)。 Bionic是 Android 改良libc的版本。Android 同時包含了Webkit,所謂的Webkit 就是Apple Safari瀏覽器背後的引擎。Surface flinger 是就2D或3D的內容顯示到屏幕上。Android使用工具鏈(Toolchain)為Google自製的Bionic Libc。
Android採用OpenCORE作為基礎多媒體框架。OpenCORE可分7大塊:PVPlayer、PVAuthor、Codec、PacketVideo Multimedia Framework(PVMF)、Operating SystemLibrary(OSCL)、Common、OpenMAX。
Android 使用skia 為核心圖形引擎,搭配OpenGL/ES。skia與Linux Cairo功能相當,但相較於Linux Cairo, skia 功能還只是陽春型的。2005年Skia公司被Google收購,2007年初,Skia GL源碼被公開,Skia 也是Google Chrome 的圖形引擎。
Android的多媒體資料庫採用SQLite資料庫系統。資料庫又分為共用資料庫及私用資料庫。用戶可通過類(Column)取得共用資料庫。
Android的中間層多以Java 實現,並且採用特殊的Dalvik虛擬機(Dalvik Virtual Machine)。Dalvik虛擬機是一種「暫存器型態」(Register Based)的Java虛擬機,變數皆存放於暫存器中,虛擬機的指令相對減少。
Dalvik虛擬機可以有多個實例(instance), 每個Android應用程序都用一個自屬的Dalvik虛擬機來運行,讓系統在運行程序時可達到優化。Dalvik虛擬機並非運行Java位元組碼(Bytecode),而是運行一種稱為.dex格式的文件。 Android 的 HAL(硬體抽像層)是能以封閉源碼形式提供硬體驅動模塊。HAL 的目的是為了把 Android framework 與 Linux kernel 隔開,讓 Android 不至過度依賴 Linux kernel,以達成 kernel independent 的概念,也讓 Android framework 的開發能在不考慮驅動程序實現的前提下進行發展。
HAL stub 是一種代理人(proxy)的概念,stub 是以 *.so 檔的形式存在。Stub 向 HAL「提供」操作函數(operations),並由 Android runtime 向 HAL 取得 stub 的 operations,再 callback 這些操作函數。HAL 里包含了許多的 stub(代理人)。Runtime 只要說明「類型」,即 mole ID,就可以取得操作函數。 Android 是運行於 Linux kernel之上,但並不是GNU/Linux。因為在一般GNU/Linux 里支持的功能,Android 大都沒有支持,包括Cairo、X11、Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。Android又以bionic 取代Glibc、以Skia 取代Cairo、再以opencore 取代FFmpeg 等等。Android 為了達到商業應用,必須移除被GNU GPL授權證所約束的部份,例如Android將驅動程序移到 userspace,使得Linux driver 與 Linux kernel徹底分開。bionic/libc/kernel/ 並非標準的kernel header files。Android 的 kernel header 是利用工具由 Linux kernel header 所產生的,這樣做是為了保留常數、數據結構與宏。
Android 的 Linux kernel控制包括安全(Security),存儲器管理(Memory Managemeat),程序管理(Process Management),網路堆棧(Network Stack),驅動程序模型(Driver Model)等。下載Android源碼之前,先要安裝其構建工具Repo來初始化源碼。Repo 是 Android 用來輔助Git工作的一個工具。
㈦ 如何編寫一個用於Android的音效驅動和控製程序
本教程將逐步講解從入門開始如何編寫一個可用於Android 4.0的音效驅動和控製程序(Android 2.3上只是部分介面不同而已)。對於Android操作系統的架構等將不再敘述。
軟體需求(Windows環境):
Windows操作系統、最新版Cygwin、Android NDK r8或更高、Eclipse、最新版Android SDK
專業技術需求:
掌握基本C/C++語法、掌握基本Java語法、基本Android UI設計、定點數學原理和演算法、基本音頻處理技術
可選高級技術需求:
IIR/FIR濾波器、FFT、Thumb/ARM匯編、NEON指令集
1、什麼是Android里的音效驅動,它是什麼架構。
從Android 2.3版開始,在系統多媒體框架里增加了一個SoundFX層,這個層就是「音效處理過程」。當多媒體系統運作時,框架允許將一個「標准」的SoundFX庫載入對應媒體流的Mixer處。SoundFX庫需要遵循OpenSLES架構,即所謂的標准就是實現一個基於OpenSLES架構的.so庫。
SoundFX可以被載入到任何一個音頻流上,每個音頻流使用會話ID作為標識符。注意:0表示系統總輸出的音頻流會話ID。一般情況下音效驅動就要載入到這個流上,才可以對系統內所有的聲音做處理(包括音視頻播放器、游戲、鈴聲等)。
同樣的,每一個SoundFX在載入時/後都有很多配置參數和控制權的優先順序。而完成對SoundFX的載入就需要一個控製程序。控製程序一般由Java語言在Eclipse中實現,通俗的說控製程序就是一個Android的apk程序。SoundFX可以理解為Windows系統里的底層混合器,控製程序可以理解為Windows的控制面板,在控制面板上控制SoundFX的載入和啟動,各個參數的設置等。當一個控製程序啟動後,它首先要做的事情就是按照OpenSLES框架來通知系統載入一個SoundFX到一個媒體流,然後通過UI交互來啟用/禁用該SoundFX,同時根據UI來控制SoundFX的參數,當退出時也需要通知系統卸載該SoundFX。
2、從哪開始?
因為Android規定SoundFX必須基於OpenSLES,所以最先要做的事情就是選擇一個效果器的類型。這是為什麼呢?到底是什麼意思呢?OpenSLES規定一個效果器要有兩個必須的條件,一個是該效果器的類型,一個是該效果器的唯一識別碼。這兩個東西在C/C++語言中是按照GUID結構體來存儲的(GUID是什麼?找度娘)。
其中類型的GUID是OpenSLES定死的,音量(SL_IID_VOLUME)、采樣率控制(SL_IID_PLAYBACKRATE)、均衡器(SL_IID_EQUALIZER)、預設混響(SL_IID_PRESETREVERB)、環境混響(SL_IID_ENVIRONMENTALREVERB)、3D定位(SL_IID_3DLOCATION)、多普勒效應(SL_IID_3DDOPPLER)、低音增強(SL_IID_BASSBOOST)、升降調(SL_IID_PITCH)、虛擬化(SL_IID_VIRTUALIZER)。這里沒有你想要的?你想自定義?什麼,你要做一個高音增強?無論做什麼,都得在這裡面選一個。為了簡單一點,那就選虛擬化吧,虛擬化只有一個固定參數。(這里沒看明白?那就把整個教程都看完,相信看到最後你會明白的)
下一步是生成一個自己獨一無二的GUID來給自己的SoundFX命名。生成的辦法有很多,有現成軟體也有網頁。這里我生成的是{42C6510E-1811-4857-8CA5-C204A8A3B0D4}。
以上提及的詳細內容和編程指導請閱讀Android NDK\platforms\android-14\arch-arm\usr\include\SLES\OpenSLES.h。(Android 4.0對應android