了解OPhone平台---OPhone平台架构和主要开发组件

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
从表面上讲,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
Content Provider提供了在不同应用程序间共享数据的机制。在OPhone系统中已经预置了几种Content Provider,向开发者提供音频、视频、图片、联系人和呼叫记录等数据。如果这些数据使用数据库接口来存储,那么将无法提供给其他的应用程序使用。当 然,如果数据只是想在应用程序内部使用,就不应该使用Content Provider,而使用数据库或者文件等可以获得更高效的读/写操作。
在android.provider包内定义了一些类和接口,它们主要描述了内置的几个Content Provider的数据结构。例如,MediaStore.Audio定义了音频数据的信息,CallLog.Calls则定义了通话记录的信息。 ContentProvider类提供了抽象的接口,允许应用程序查询,插入,删除和更新其中的数据。下面的代码可以从系统中查询存储在SD卡上的歌曲, 如图3所示:
view plain copy to clipboard print ?
  1. ContentResolver resolver = getContentResolver();  
  2. //从Content Provider中获得SD卡上的音乐列表   
  3. cursor =resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,  
  4.        nullnullnull , MediaStore.Audio.Media.DEFAULT_SORT_ORDER);  
  5. String[] cols = new  String[] { MediaStore.Audio.Media.TITLE,  
  6.        MediaStore.Audio.Media.ARTIST, };  
  7. int [] ids =  new   int [] { R.id.track_name, R.id.artist };  
  8. if  (cursor !=  null )  
  9.        startManagingCursor(cursor);  
  10. //创建Adapter并绑定到ListView   
  11. SimpleCursorAdapter adapter = new  SimpleCursorAdapter( this ,  
  12.        R.layout.songs_list, cursor, cols, ids);  
  13. 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并绑定到ListView
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.songs_list, cursor, cols, ids);
setListAdapter(adapter);
图3 列举SD卡上的歌曲
  • Service
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()会被调用,因此与资源释放相关的工作应该在此方法中完成。
  • BroadcastReceiver
应用程序的运行环境不是一成不变的,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 ?
  1. <receiver android:name= ".BootReceiver"  >  
  2. <intent-filter>  
  3.         <action android:name="android.intent.action.BOOT_COMPLETED"  />  
  4.  </intent-filter>  
  5. </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 ?
  1. <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 ?
  1. public   class  BootReceiver  extends  BroadcastReceiver {  
  2.    
  3.    
  4.        @Override   
  5.        public   void  onReceive(Context arg0, Intent arg1) {  
  6.               if  (arg1.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {  
  7.                      Intent intent = new  Intent(arg0, com.ophone.MusicActivity. class );  
  8.                      //在Activity之外调用startActivity()   
  9.                      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  10.                      arg0.startActivity(intent);  
  11.               }  
  12.        }  
  13. }  
  14.    
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之外调用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年荣获电子工业出版社优秀作者奖。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用 OpenStack CLI - 每天5分钟玩转 OpenStack(22)

本节首先讨论 image 删除操作&#xff0c;然后介绍 OpenStack CLI 的使用方法&#xff0c;最后讨如何 Troubleshoot。 Web UI 删除 image admin 登录后&#xff0c;Project -> Compute -> Images在列表中选择格式为 ARI 和 AKI 的 image&#xff0c;点击点击确认删除 …

异步复位的串联T触发器

异步复位的串联T触发器 T触发器的特征方程 Qn1 T Qn ’ T ’ Qn T⊕Qn T触发器的特征表 信号示意图 timescale 1ns/1ns module Tff_2 ( input wire data, clk, rst, output reg q ); //*************code***********//reg m;always(posedge clk or negedge rst)beginif…

Pause/Resume Instance 操作详解 - 每天5分钟玩转 OpenStack(34)

本节通过日志详细分析 Nova Pause/Resume 操作。 有时需要短时间暂停 instance&#xff0c;可以通过 Pause 操作将 instance 的状态保存到宿主机的内存中。当需要恢复的时候&#xff0c;执行 Resume 操作&#xff0c;从内存中读回 instance 的状态&#xff0c;然后继续运行 ins…

Windows® CE 系统中的同步机制

看到篇好文章&#xff0c;呵呵&#xff0c;独乐乐&#xff0c;不如众乐乐 本文转自http://blog.csdn.net/thl789/archive/2006/01/17/582246.aspx &#xff0c;转载请注明出处 摘要 ... 1 目录 ... 1 一、 WinCE进程 /线程模型概览 ... 1 二、临…

Nova Suspend/Rescue 操作详解 - 每天5分钟玩转 OpenStack(35)

本节我们讨论 Suspend/Resume 和 Rescue/Unrescue 这两组操作。 Suspend/Resume 有时需要长时间暂停 instance&#xff0c;可以通过 Suspend 操作将 instance 的状态保存到宿主机的磁盘上。当需要恢复的时候&#xff0c;执行 Resume 操作&#xff0c;从磁盘读回 instance 的状态…

关于奇偶校验

关于奇偶校验 奇校验(Odd Parity)&#xff1a;所有传送的数位&#xff08;含字符的各数位和校验位&#xff09;中&#xff0c;“1”的个数为奇数&#xff0c;如&#xff1a; 1 0110&#xff0c;0101 0 0110&#xff0c;0101 偶校验(Even Parity)&#xff1a;所有传送的数位&am…

移位运算与乘法

移位运算与乘法 题目描述 已知d为一个8位数&#xff0c;请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效&#xff08;d给出的信号的上升沿表示写入有效&#xff09; 信号示意图 波形示意图 timescale 1ns/1ns module multi_sel( input [7:0]d …

Snapshot Instance 操作详解 - 每天5分钟玩转 OpenStack(36)

本节我们通过日志详细讨论 instance 的 snapshot 操作。 有时候操作系统损坏得很严重&#xff0c;通过 Rescue 操作无法修复&#xff0c;那么我们就得考虑通过备份恢复了。当然前提是我们之前对instance做过备份。 Nova 备份的操作叫 Snapshot&#xff0c;其工作原理是对 insta…

Rebuild Instance 操作详解 - 每天5分钟玩转 OpenStack(37)

上一节我们讨论了 snapshot&#xff0c;snapshot 的一个重要作用是对 instance 做备份。 如果 instance 损坏了&#xff0c;可以通过 snapshot 恢复&#xff0c;这个恢复的操作就是 Rebuild。 Rebuild 会用 snapshot 替换 instance 当前的镜像文件&#xff0c;同时保持 instanc…

突发传输模式

突发传输模式 突发传输(Burst transmission),一般也称为数据突发,其在通信领域中一般指在短时间内进行相对高带宽的数据传输。 突发传输一般表示的是两个设备之间进行数据传送的一种模式,也可将其称为突发模式下的数据传输。而突发(Burst)是指在同一行中相邻的存储单元…

Waveform Audio 驱动(Wavedev2)之:WAV 驱动解析

Waveform Audio 驱动(Wavedev2)之&#xff1a;WAV 驱动解析 上篇文章中&#xff0c;我们模拟了WAV API。现在进入我们正在要解析的Wave 驱动的架构。我们了解一个驱动的时候&#xff0c;先不去看具体跟硬件操作相关的东西&#xff0c;而是从流程入手&#xff0c;把整个流程搞清…

Unshelve Instance 操作详解 - 每天5分钟玩转 OpenStack(39)

上一节我们 shelve instance 到 Glance&#xff0c;本节讨论如何通过 unshelve 操作恢复该 instance。 因为 Glance 中保存了 instance 的 image&#xff0c;unshelve 的过程其实就是通过该 image launch 一个新的 instance&#xff0c;nova-scheduler 也会调度合适的计算节点来…

位拆分与运算

位拆分与运算 题目描述 现在输入了一个压缩的16位数据&#xff0c;实际上包含了四个数据[3:0][7:4][11:8][15:12] 按照sel选择输出四个数据的相加结果&#xff0c;并输出valid_out信号&#xff08;在不输出时候拉低&#xff09; 0&#xff1a;输出[3:0][7:4] 1&#xff1a;输出…

得意而忘乎形:谈葛水平的水墨画

不知道葛水平早年学过画没有&#xff0c;只知道她搞过戏曲&#xff0c;好像也有过舞台表演的经验。现在主要写小说&#xff0c;成绩斐然&#xff0c;创作之余画水墨。贾平凹看了她的画后说&#xff1a;“每个人都有绘画潜质&#xff0c;只是大与小和开发与不开发。”这话有理。…

Eclipse安装Perl插件

http://www.cnblogs.com/emanlee/archive/2012/08/11/2633701.html Eclipse安装Perl EPIC插件,在Eclipse中开发Perl项目 前提&#xff1a; 已经安装了 Eclipse&#xff0c;Java&#xff0c;Perl(例如 ActivePerl)。 步骤&#xff1a; 启动Eclipse&#xff0c;Eclipse中&#x…

风鬣霜蹄马王出

今年夏天&#xff0c;在内蒙古莱德马业繁殖基地的母马放养草场,我看到一群特殊的马点缀在绿色的草原之中。它们的颜色令我大开眼界&#xff1a;黑、白、枣红、黄骠、铁青……远远望去&#xff0c;五颜六色&#xff0c;神态各异。莱德马业的负责人朱方清告诉我&#xff0c;这里除…

多功能数据处理器

多功能数据处理器 题目描述 根据指示信号select&#xff0c;对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数&#xff0c;当select信号为0&#xff0c;输出a&#xff1b;当select信号为1,输出b&#xff1b;当select信号为2&#xff0c;输出ab;当select信号为3&#x…

Live Migrate 操作 - 每天5分钟玩转 OpenStack(42)

Migrate 操作会先将 instance 停掉&#xff0c;也就是所谓的“冷迁移”。而 Live Migrate 是“热迁移”&#xff0c;也叫“在线迁移”&#xff0c;instance不会停机。 Live Migrate 分两种&#xff1a; 源和目标节点没有共享存储&#xff0c;instance 在迁移的时候需要将其镜像…

计算节点宕机了怎么办?- 每天5分钟玩转 OpenStack(43)

Rebuild 可以恢复损坏的 instance。 那如果是宿主机坏了怎么办呢&#xff1f; 比如硬件故障或者断电造成整台计算节点无法工作&#xff0c;该节点上运行的 instance 如何恢复呢&#xff1f; 用 Shelve 或者 Migrate 可不可以&#xff1f; 很不幸&#xff0c;这两个操作都要求 i…

eclipse 全屏插件

eclipse-fullscreen 插件下载链接&#xff1a; http://code.google.com/p/eclipse-fullscreen/&#xff0c; 安装方式&#xff1a;将下载下来的压缩文件解压&#xff0c;将里边的jar包放到eclipse目录下的plugin文件夹中&#xff0c;重启eclipse即可。 在Fedora & Windows …