OPhone平臺架構(gòu)和主要開發(fā)組件
OPhone平臺的架構(gòu)
OPhone平臺由底層操作系統(tǒng)、本地系統(tǒng)庫、OPhone運行環(huán)境、Widget運行環(huán)境、應(yīng)用程序框架和應(yīng)用程序等部分組成。OPhone平臺結(jié)構(gòu)圖如圖1所示:
OPhone平臺基于Linux 2.6版內(nèi)核,內(nèi)核為上層系統(tǒng)提供了安全、內(nèi)存管理、線程管理、網(wǎng)絡(luò)協(xié)議棧和驅(qū)動模型等系統(tǒng)服務(wù)。OPhone平臺強大的功能來源于底層的本地庫,包括多媒體引擎OpenCORE,瀏覽器引擎WebKit,2D圖形引擎SGL和關(guān)系型數(shù)據(jù)庫SQLite等。這些本地庫通過上層的應(yīng)用程序框架將編程接口提供給開發(fā)者調(diào)用,本地庫和應(yīng)用程序框架通過JNI(Java Native Interface)連接。OPhone平臺為應(yīng)用程序提供了一個開放的運行環(huán)境,無論是內(nèi)置應(yīng)用程序,還是后續(xù)安裝的應(yīng)用程序,所有應(yīng)用程序訪問底層框架的能力是一致的,開發(fā)者可以使用應(yīng)用程序框架提供的API開發(fā)自己的應(yīng)用程序。
OPhone上的應(yīng)用程序模型
最新發(fā)布的OPhone 1.5平臺支持以下三種應(yīng)用程序,本文主要介紹OPhone應(yīng)用程序模型。
使用java語言編寫的OPhone應(yīng)用程序,以APK形式發(fā)布。
使用HTML、JavaScript等腳本語言編寫的Widget程序,以WGT形式發(fā)布。
使用java語言編寫的MIDlet程序,以jar/jad形式發(fā)布。
APK文件在Dalvik虛擬機內(nèi)運行,Dalvik虛擬機與普通的Java虛擬機不同,它針對嵌入式設(shè)備進行了優(yōu)化,class文件也經(jīng)過“dx”工具轉(zhuǎn)換成.dex文件格式,.dex文件格式更為緊湊,執(zhí)行效率更高。APK應(yīng)用程序運行時,OPhone會啟動一個Linux進程,應(yīng)用程序就運行在自己的進程之中。每一個進程都擁有自己的一個Java虛擬機,不同應(yīng)用程序的代碼都是單獨運行的,不會相互影響。
APK是一種與zip文件格式兼容的文件。OPhone SDK提供了aapt工具,可以把類文件和資源文件打包成APK文件,打包過程包括class文件到dex文件的轉(zhuǎn)換、生成資源表、優(yōu)化文本格式的XML文件等工作。轉(zhuǎn)換過程如圖2所示:
主要開發(fā)組件
OPhone應(yīng)用程序通常由Activity、Content Provider、Service和BroadcastReceiver組成,雖然每項并非是必須的,但是掌握這些開發(fā)組件是學(xué)習(xí)OPhone應(yīng)用程序開發(fā)首要的任務(wù)。下面對OPhone應(yīng)用程序的主要開發(fā)組件逐一介紹。#t#
Activity
從表面上講,Activity是OPhone應(yīng)用程序的一個界面,用戶可以通過這個界面操作播放器,查看聯(lián)系人或者玩游戲。對開發(fā)者而言,Activity是OPhone應(yīng)用程序的入口,OPhone應(yīng)用程序模型沒有定義像main()這樣的入口方法,而是在Activity類中定義了一系列的生命周期方法,比如onCreate()、onResume()、onStart()、onPause()、onStop()和onDestroy(),OPhone系統(tǒng)會在適當?shù)臅r候調(diào)用對應(yīng)的生命周期方法。這一點與Java ME平臺的MIDlet類似。#p#
OPhone的應(yīng)用程序模型打破了應(yīng)用程序之間的邊界,系統(tǒng)會為每個應(yīng)用程序維持一個堆棧,堆棧中放置Activity對象,應(yīng)用程序不但可以將APK中定義的Activity放入堆棧,還可以將其他應(yīng)用程序的Activity放入堆棧中。例如,可以通過調(diào)用startActivity()方法啟動瀏覽器、撥打電話、瀏覽圖片等。例如,從應(yīng)用程序中調(diào)用Phone程序撥打電話的代碼如下所示:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:10086"));
startActivity(intent);
這種特性極大的增加了平臺組件的復(fù)用性,你不需要單獨開發(fā)一個電話程序,也沒有必要單獨開發(fā)一個圖片瀏覽程序,只需要通過簡單的代碼調(diào)用系統(tǒng)已經(jīng)提供的Activity即可。
Content Provider
Content Provider提供了在不同應(yīng)用程序間共享數(shù)據(jù)的機制。在OPhone系統(tǒng)中已經(jīng)預(yù)置了幾種Content Provider,向開發(fā)者提供音頻、視頻、圖片、聯(lián)系人和呼叫記錄等數(shù)據(jù)。如果這些數(shù)據(jù)使用數(shù)據(jù)庫接口來存儲,那么將無法提供給其他的應(yīng)用程序使用。當然,如果數(shù)據(jù)只是想在應(yīng)用程序內(nèi)部使用,就不應(yīng)該使用Content Provider,而使用數(shù)據(jù)庫或者文件等可以獲得更高效的讀/寫操作。
在android.provider包內(nèi)定義了一些類和接口,它們主要描述了內(nèi)置的幾個Content Provider的數(shù)據(jù)結(jié)構(gòu)。例如MediaStore.Audio定義了音頻數(shù)據(jù)的信息,CallLog.Calls則定義了通話記錄的信息。ContentProvider類提供了抽象的接口,允許應(yīng)用程序查詢,插入,刪除和更新其中的數(shù)據(jù)。下面的代碼可以從系統(tǒng)中查詢存儲在SD卡上的歌曲,如圖3所示:
- ContentResolver resolver = getContentResolver();
- //從Content Provider中獲得SD卡上的音樂列表
- cursor =resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); String[] cols = new String[] {
- MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST,
- };
- int[] ids = new int[] { R.id.track_name, R.id.artist };
- if (cursor != null) startManagingCursor(cursor);
- //創(chuàng)建Adapter并綁定到ListView SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.songs_list, cursor, cols, ids);
- setListAdapter(adapter);
Service
Service是OPhone平臺非常重要的組件之一,它運行在后臺,不與用戶進行交互。在默認情況下,Service運行在應(yīng)用程序進程的主線程之中,如果需要在Service中處理一些網(wǎng)絡(luò)連接等耗時的操作,那么應(yīng)該將這些任務(wù)放在單獨的線程中處理,避免阻塞用戶界面。啟動后的Service具有較高的優(yōu)先級,一般情況下,系統(tǒng)會保證Service的正常運行。只有當前臺的Activity正常運行的資源被Service占用的情況下,系統(tǒng)才會暫時停止Service;當系統(tǒng)重新獲得了資源后會自動啟動原來的Service。
如果想使用Service組件,需要擴展android.app.Service類,并在AndroidManifest.xml文件中使用
BroadcastReceiver
應(yīng)用程序的運行環(huán)境不是一成不變的,SD卡插拔、電池電量低等事件會影響應(yīng)用程序的運行。為了能夠做出正確的響應(yīng),應(yīng)用程序必須能夠監(jiān)聽此類事件并做出正確的處理。在OPhone系統(tǒng)中,BroadcastReceiver就是我們需要的那個組件。BroadcastReceiver沒有界面顯示,但是它卻可以通過AndroidManifest.xml或者在代碼中進行注冊,以監(jiān)聽應(yīng)用程序感興趣的事件。BroadcastReceiver是一個抽象類,定義了一個抽象方法onReceive(),當廣播事件到來時,BroadcastReceiver的onReceive()方法會被調(diào)用,開發(fā)者只需要自己實現(xiàn)此方法即可。
void onReceive(Context curContext, Intent broadcastMsg)
使用BroadcastReceiver可以方便的實現(xiàn)開機自啟動應(yīng)用程序,OPhone系統(tǒng)啟動后,會廣播Intent.ACTION_BOOT_COMPLETED事件,因此只需要在程序中定義一個BroadcastReceiver并在AndroidManifest.xml中進行注冊。
- <receiver android:name=".BootReceiver" >
- <intent-filter> <action android:name="android.intent.action.BOOT_
- COMPLETED" /> < span>intent-filter> < span>receiver>
除此之外,還需要在AndroidManifest.xml中增加權(quán)限聲明,如果不聲明應(yīng)用程序所需要的權(quán)限,那么在運行時會拋出安全異常。
- <uses-permission android:name="android.permission.RECEIVE_BOOT_
- COMPLETED"/>
- <uses-permission android:name="android.permission.RECEIVE_BOOT_
- COMPLETED"/>
最后只需要實現(xiàn)一個BroadcastReceiver即可,代碼如下所示:
- public class BootReceiver extends BroadcastReceiver
- { @Override public void onReceive(Context arg0, Intent arg1)
- { if (arg1.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
- {Intent intent = new Intent(arg0, com.ophone.MusicActivity.class); //在Activity之外調(diào)用startActivity()
- intent.addFlag
- (Intent.FLAG_ACTIVITY_NEW_TASK);
- arg0.startActivity(intent); } } }