OPhone平臺基于Linux和開放手機聯盟(OHA)的Android系統,經過中國移動的創新研發,設計出擁有新穎獨特的用戶操作界面,增強 了瀏覽器能力和WAP兼容性,優化了多媒體領域的OpenCORE、瀏覽器領域的WebKit等業內眾多知名引擎,增加了包括游戲、Widget、 Java ME等在內的先進平臺中間件。本文主要介紹OPhone的架構、應用程序模型和主要開發組件。
OPhone平臺的架構
OPhone 平臺由底層操作系統、本地系統庫、OPhone運行環境、Widget運行環境、應用程序框架和應用程序等部分組成。OPhone平臺結構圖如圖1所示:
圖1 OPhone平臺的架構圖
OPhone平臺基于Linux 2.6版內核,內核為上層系統提供了安全、內存管理、線程管理、網絡協議棧和驅動模型等系統服務。 OPhone 平臺強大的功能來源于底層的本地庫,包括多媒體引擎OpenCORE,瀏覽器引擎WebKit,2D圖形引擎SGL和關系型數據庫SQLite等。這些本 地庫通過上層的應用程序框架將編程接口提供給開發者調用,本地庫和應用程序框架通過JNI(Java Native Interface)連接。OPhone平臺為應用程序提供了一個開放的運行環境,無論是內置應用程序,還是后續安裝的應用程序,所有應用程序訪問底層框 架的能力是一致的,開發者可以使用應用程序框架提供的API開發自己的應用程序。
OPhone上的應用程序模型
最新發布的OPhone 1.5平臺支持以下三種應用程序,本文主要介紹OPhone應用程序模型。
- 使用java語言編寫的OPhone應用程序,以APK形式發布。
- 使用HTML、JavaScript等腳本語言編寫的Widget程序,以WGT形式發布。
- 使用java語言編寫的MIDlet程序,以jar/jad形式發布。
APK文件在Dalvik虛擬機內運行,Dalvik虛擬機與普通的Java虛擬機不同,它針對嵌入式設備進行了優化,class文件也經過 “dx”工具轉換成.dex文件格式,.dex文件格式更為緊湊,執行效率更高。APK應用程序運行時,OPhone會啟動一個Linux進程,應用程序 就運行在自己的進程之中。每一個進程都擁有自己的一個Java虛擬機,不同應用程序的代碼都是單獨運行的,不會相互影響。
APK是一種與zip文件格式兼容的文件。OPhone SDK提供了aapt工具,可以把類文件和資源文件打包成APK文件,打包過程包括class文件到dex文件的轉換、生成資源表、優化文本格式的XML文件等工作。轉換過程如
圖2所示:
圖2 項目文件到APK文件轉換過程
主要開發組件
OPhone 應用程序通常由Activity、Content Provider、Service和BroadcastReceiver組成,雖然每項并非是必須的,但是掌握這些開發組件是學習OPhone應用程序開發首要的任務。下面對OPhone應用程序的主要開發組件逐一介紹。
從表面上講,Activity是OPhone應用程序的一個界面,用戶可以通過這個界面操作播放器,查看聯系人或者玩游戲。對開發者而 言,Activity是OPhone應用程序的入口,OPhone應用程序模型沒有定義像main()這樣的入口方法,而是在Activity類中定義了 一系列的生命周期方法,比如onCreate()、onResume()、onStart()、onPause()、onStop()和 onDestroy(),OPhone系統會在適當的時候調用對應的生命周期方法。這一點與Java ME平臺的MIDlet類似。
OPhone 的應用程序模型打破了應用程序之間的邊界,系統會為每個應用程序維持一個堆棧,堆棧中放置 Activity對象,應用程序不但可以將APK中定義的Activity放入堆棧,還可以將其他應用程序的Activity放入堆棧中。例如,可以通過 調用startActivity()方法啟動瀏覽器、撥打電話、瀏覽圖片等。例如,從應用程序中調用Phone程序撥打電話的代碼如下所示:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:10086"));
startActivity(intent);
這種特性極大的增加了平臺組件的復用性,你不需要單獨開發一個電話程序,也沒有必要單獨開發一個圖片瀏覽程序,只需要通過簡單的代碼調用系統已經提供的Activity即可。
Content Provider提供了在不同應用程序間共享數據的機制。在OPhone系統中已經預置了幾種Content Provider,向開發者提供音頻、視頻、圖片、聯系人和呼叫記錄等數據。如果這些數據使用數據庫接口來存儲,那么將無法提供給其他的應用程序使用。當 然,如果數據只是想在應用程序內部使用,就不應該使用Content Provider,而使用數據庫或者文件等可以獲得更高效的讀/寫操作。
在android.provider包內定義了一些類和接口,它們主要描述了內置的幾個Content Provider的數據結構。例如,MediaStore.Audio定義了音頻數據的信息,CallLog.Calls則定義了通話記錄的信息。 ContentProvider類提供了抽象的接口,允許應用程序查詢,插入,刪除和更新其中的數據。下面的代碼可以從系統中查詢存儲在SD卡上的歌曲, 如圖3所示:
view plain copy to clipboard print ?
ContentResolver?resolver?=?getContentResolver();?? ?? 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);?? ?? SimpleCursorAdapter?adapter?=?new ?SimpleCursorAdapter( this ,?? ???????R.layout.songs_list,?cursor,?cols,?ids);?? setListAdapter(adapter);?? 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);//創建Adapter并綁定到ListViewSimpleCursorAdapter adapter = new SimpleCursorAdapter(this,R.layout.songs_list, cursor, cols, ids);setListAdapter(adapter);
圖3 列舉SD卡上的歌曲
Service是OPhone平臺非常重要的組件之一,它運行在后臺,不與用戶進行交互。在默認情況下,Service運行在應用程序進程的 主線程之中,如果需要在Service中處理一些網絡連接等耗時的操作,那么應該將這些任務放在單獨的線程中處理,避免阻塞用戶界面。啟動后的 Service具有較高的優先級,一般情況下,系統會保證Service的正常運行。只有當前臺的Activity正常運行的資源被Service占用的 情況下,系統才會暫時停止Service;當系統重新獲得了資源后會自動啟動原來的Service。
如果想使用Service組件,需要擴展android.app.Service類,并在AndroidManifest.xml文件中使 用<service>標簽聲明。與Activity類似,Service中同樣定義了onCreate()、onStart()和 onDestroy()等生命周期方法。當其他組件通過Context.startService()方法啟動Service時,系統會創建一個 Service對象,并順序調用onCreate()方法和onStart()方法。在調用Context.stopService()或者 stopSelf()之前,Service一直處于運行的狀態。如果多次調用startService()方法,系統只會多次調用onStart()方 法,而不會重復調用onCreate()方法。無論調用了多少次startService(),只需要調用一次stopService()就可以停止 Service。Service對象在銷毀之前,onDestroy()會被調用,因此與資源釋放相關的工作應該在此方法中完成。
應用程序的運行環境不是一成不變的,SD卡插拔、電池電量低等事件會影響應用程序的運行。為了能夠做出正確的響應,應用程序必須能夠監聽此類事 件并做出正確的處理。在OPhone系統中,BroadcastReceiver就是我們需要的那個組件。BroadcastReceiver沒有界面顯 示,但是它卻可以通過AndroidManifest.xml或者在代碼中進行注冊,以監聽應用程序感興趣的事件。BroadcastReceiver是 一個抽象類,定義了一個抽象方法onReceive(),當廣播事件到來時,BroadcastReceiver的onReceive()方法會被調用, 開發者只需要自己實現此方法即可。
void onReceive(Context curContext, Intent broadcastMsg)
使用BroadcastReceiver可以方便的實現開機自啟動應用程序,OPhone系統啟動后,會廣播 Intent.ACTION_BOOT_COMPLETED事件,因此只需要在程序中定義一個BroadcastReceiver并在 AndroidManifest.xml中進行注冊。
view plain copy to clipboard print ?
<receiver?android:name= ".BootReceiver" ?>?? <intent-filter>?? ????????<action?android:name="android.intent.action.BOOT_COMPLETED" ?/>?? ?</intent-filter>?? </receiver>??
<receiver android:name=".BootReceiver" >
<intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter>
</receiver>
除此之外,還需要在AndroidManifest.xml中增加權限聲明,如果不聲明應用程序所需要的權限,那么在運行時會拋出安全異常。
view plain copy to clipboard print ?
<uses-permission?android:name= "android.permission.RECEIVE_BOOT_COMPLETED" />??
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
最后只需要實現一個BroadcastReceiver即可,代碼如下所示:
view plain copy to clipboard print ?
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 );?? ????????????????????? ?? ?????????????????????intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);?? ?????????????????????arg0.startActivity(intent);?? ??????????????}?? ???????}?? }?? ???
public class BootReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context arg0, Intent arg1) {if (arg1.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {Intent intent = new Intent(arg0, com.ophone.MusicActivity.class);//在Activity之外調用startActivity()intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);arg0.startActivity(intent);}}
}
更多內容歡迎大家訪問OPhone開發者社區(www.ophonesdn.com )。
作者介紹
詹建飛,中國移動通信研究院終端技術研究所項目經理。6年java編程經驗,熟悉Java ME,Symbian,OPhone/Android等多種移動開發平臺,具有豐富的客戶端軟件開發和設計經驗。先后出版了《J2ME開發精解》、 《Java ME核心技術與最佳實踐》和《OPhone應用開發權威指南》等書籍,2007年榮獲電子工業出版社優秀作者獎。
總結
以上是生活随笔為你收集整理的了解OPhone平台---OPhone平台架构和主要开发组件的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。