版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
手机Android平台的相关知识详述
Android是Google于2007年11月05日宣布的基于Linux平台的开源手机操作
系统的名称,该平台由操作系统、中间件、用户界面与应用软件构成。它使用软
件堆层(SoftwareStack,又名软件叠层)的架构,要紧分为三部分。底层以Linux
内核工作为基础,由C语言开发,只提供基本功能;中间层包含函数库Library
与虚拟机VirtualMachine,由C++开发。最上层是各类应用软件,包含通话程
序,短信程序等,应用软件则由各公司自行开发,以Java作为编写程序的--部
分。不存在任何以往阻碍移动产业创新的专有权障碍,号称是首个为移动终端打
造的真正开放与完整的移动软件。
S60,即Series60。是诺基亚为Symbian系统开发的一个UI(用户界面),S60不是手机系统,
而是一个基于Symbian系统的月户图形操作界面。
AndyRubin创立了两个手机操作系统公司:Danger与AndroidoDanger5亿美元卖给微软,
今年成为了Kin,Android4F万美元卖给Google。Android是Google于2007年11月05
日宣布的基于Linux平台的开源移动操作系统的名称,该平台由操作系统、中间件、用户
界面与应用软件构成。它使用软件堆层(SoftwareStack,又名软件登层)的架构,要紧
分为三部分。底层以Linux内核工作为基础,
android系统效果图
由C语言开发,只提供基本功能:中间层包含函数库Library与虚拟机VirtualMachine,
由C++开发。最上层是各类应用软件,包含通话程序,短信程序等,应用软件则由各公
司自行开发,以Java作为编写程序的一部分。不存在任何以在阻碍移动产业创新的专有
权障碍,号称是首个为移动终端打造的真正开放与完整的移动软件。Google通过与软、
硬件开发商、设备制造商、电信运营商等其他有关各方结成深层次的合作伙伴关系,希
望借助建立标准化、开放式的移动电话软件平台,在移动产业内形成一个开放式的生态
系统。Android作为Google企业战略的重要构成部分,将进一步推进“随时随地为每个
人提供信息''这一企业目标的实现。全球为数众多的移动电话用户正在使用各类基于
Android的电话。谷歌的目标是让(移动通讯)不依鸵于设备共至平台。出于这个目的,
Android将补充,而不可能替代谷歌长期以来奉行的移动进展战略:通过与全球各地的手
机制造商与移动运营商结成合作伙伴,开发既有用乂有吸用力的移动服务,并推广这些
产品。
android系统特性
应用程序框架支持组件的重用与替换-Dalvik虚拟机专门为移动设备做了优
化•内部集成浏览器该浏览器基于开源的WebKit引擎•优化的图形库包含2D与3D
图形库,
android
3D图形库基于OpenGLES1.0(硬件加速可选)用SQLite用作结构化的数据存储•多
媒体支持包含常见的音频、视频与静态印象文件格式(如MPEG4.H.264.MP3.AAC.
AMR,JPG,PNG,GIF)GSM电话(依靠于硬件)・蓝牙Bluetooth,EDGE.3G.andWiFi
(依匏于硬件)•照相机,GPS,指南针,与加速度计(依靠于硬件)♦丰富的开发环
境包含设备模拟器,调试工具,内存及性能分析图表,与氏lipse集成开发环境插件
android系统架构
架构详解
现在我们拿起r•术刀来剖析各个部分。事实上这部分SDK文档已经帮我们做得很好
了,我们要做的就是拿来主义,然后再加上自己懂得0下面白底向上分析各层。
android
1、LinuxKernel
Android基于Linux2.6提供核心系统服务,比如:安全、内存管理、进程管理、网
络堆栈、驱动模型。LinuxKernel也作为硬件与软件之间的抽象层,它隐藏具体硬件细节
而为上层提供统一的服务。假如你学过计算机网络明白OSHRM,就会明白分层的好处
就是使用下层提供的服务而为上层提供统一的服务,屏蔽本层及下列层的差异,当本层
及下列层发生了变化不可能影响到上层。也就是说各层各尽其职,各层提供固定的SAP
(ServiceAccessPoint),专业点能够说是高内聚、低耦合。假如你只是做应用开发,
就不需要深入熟悉LinuxKernel层。
2、AndroidRuntime
Android包含一个核心库的集合,提供大部分在Java编程语言核心类库中可用的功
能。每一个Android应用程序是Dalvik虚拟机中的实例,运行在他们自己的进程中。Dalvik
虚拟机设计成,在一个设备能够高效地运行多个虚拟机。Dalvik虚拟机可执行文件格式
是.dcx,dcx格式是专为Dalvik设计的一种压缩格式,适合内存与处理器速度有限的系统。
大多数虚拟机包含JVM都是基于栈的,而Dalvik虚拟机则是基于寄存器的。两种架构各
有优劣,通常而言,基丁•枝的机器需要更多指令,而基于寄存器的机器指令更大。dx是
一套工具,能够将Java.class转换成.dex格式。一个dex文件通常会有多个.class。由
于dex有的时候务必进行最佳化,会使文件大小增加1-4倍,以ODEX结尾。DaNik虚
拟机依够于Linux内核提供基本功能,如线程与底层内存管埋。
3、Library
Android包含一个C/C++库的集合,供Android系统的各个组件使用。这些功能通过
Android的应用程序框架(applicationframework)暴露给开发者。下面列出一些核心库:
系统C库——标准C系统库(libc)的BSD衍生,调整为基于嵌入式Linux设备媒体库
-基于PackctVidco的OpcnCORE。这些库支持播放与录制许多流行的音频与视频格式,
与静态图像文件,包含MPEG4、H.264、MP3、AAC、AMR、JPG、PNG界面管
理——管理访问显示子系统与无缝组合多个应用程序的二维与三维图形层
LibWebCore——新式的Web浏览器引擎,驱动Android浏览器与内嵌的web视图
SGL——基本的2D图形引擎3D库——基于OpenGLESI.OAPIs的实现。库使用硬件
3D加速或者包含高度优化的3D软件光栅FreeType——位图与矢量字体渲染SQLite
——所有应用程序都能够使用的强大而轻量级的关系数据库引擎
4、ApplicationFramework
通过提供开放的开发平台,Android使开发者能够编制极其丰富与新颖的应用程序。
开发者能够自由地利用设备硬件优势、访问位置信息、运行后台服务、设置闹钟、向状
态栏添加通知等等,很多很多。开发者能够完全使用核心应用程序所使用的框架APIs。
应用程序的体系结构旨在简化组件的重用,任何应用程序都能公布他的功能且任何其他
应用程序能够使用这些功能:需要服从框架执行的安全限制)。这一机制同意用户替换
组件。所有的应用程序事实上是一组服务与系统,包含:视图(View)——丰富的、
可扩展的视图集合,可用于构建一个应用程序。包含包含列表、网格、文本框、按钮,
甚至是内嵌的网页浏览器内容提供者(ContentProviders)——使应用程序能访问其他
学习的一种手段。
其下所有内容,估计有十数篇,抑或者更多。基本与技术有关,也许会配有一些其他有关比较闲淡的话题。
可能会有一些具象实例,但更多的可能是自己的一些懂得与认知。所有一切,源自于妄自挖掘,难免有疏
漏或者误解,观者淡定。
以此为序,有心者,望共勉。
Android简史
人生若只初识,何事秋风悲画扇。-《木兰辞》
要说当今移动平台的当红辣子鸡,Android说它是第二,也许没有别家敢认这个第一(好吧,iPhone.有
意见就说…〉°熟悉Android开发平台的过去与现状,除了往下看,另有便利的方式就是在WikiPedia中
键入Android,在这里,特此鸣谢GFW友情放生。
诞生
早在2005年7月,Google舞动者手中的美刀,收下了由AndyRubin(传说中的Android之父…)等人创
立的一家小公司,他们当时做的就是基于Linux内核的手机操作系统,也就是小时候的Android。通过Google
多年打磨,Android在07年末,正二八经的粉墨登场开门接客。
自打一出生,Android便被钉板在就一代的角色上,不仅是由于老翁有钱的令人发指,也是由于其后有一
帮金光闪耀的叔伯们保驾护航。这个叔伯群,便是响当当的开放手机联盟OHA(OpenHandsetAlliance).
这个联盟涵盖了中国移动、『Mobile、Sprint这样的移动运营商,也包含HTC、Motolora、三星这些的手
机制造商,同时还有以Google为代表的手机软件商,以Inter,Nvidia为标志的底层硬件厂商与Astonishing
Tribe这样的商业运作公司(这公司是啥我也不晓得.作为后援团,他们理论上的任务,是各尽其长,
全力捧红Android.实际上的任务是齐心协力,借Android东风赚一个盆沐满响。
当然,Android自因此被万众瞩目一炮走红,不仅仅是丫实在太有背景,同时,它也有这太多的新鲜的概
念。Android是一个开源的平台(恩,真正的全面开源,是在公布后很久以后了…),它给那些捂着自家平
台源码当宝的竞争对手们一记当头棒喝。Android自行研发了一套Java虚拟机,当时仅提供JavaAPI的
支持(NDK是更久以后的情况了…),号称之专为高端智能设计。Android开发环境支持所有主流操作系
统平台,包含Windows.Linux.Mac,即便到今天,在手机开发中也是吸其罕见的。Android的带头人
Google.本身是做网络起家,Android内嵌大殳Google网络应用,听上去就显得很酷。这所有的一切,共
同造就了Android那鹤立鸡群,不柒风尘的少侠形象。
造势
推出伊始,Google还有一个很震框的推广举动,就是举行所谓的Android程序挑战赛(AndroidDeveloper
Challenge,ADC)a整个比赛分成两场,第一场(ADC1)比赛,在没有任何真机问世,SDK还是个雏形
的状况下,便鸣金开锣了。
比赛套路是无差别的群殴,基本概念是不管你来自何方(还是要满足美国法律要求与避嫌要求的),不管
你想做些什么,也不管你是光杆司令还是流岷团伙,只要提交一个能在模拟器上跑起来的程序,就可参赛。
而比赛只是对你作品进行参观评比,作品的所有权依然放在开发者的口袋中。
当然,这还不算什么创新,NB的是无比丰厚的奖金,整个ADC的奖金而达1千万美刀,每场各半,基本
上首轮入围奖(前50)已经超越了那时候通常程序比赛的头名奖金,这对很多小公司与个人而言,无疑是
具有很强吸引力的。因此,各路打酱油好手蜂拥而至,各论坛、博客、网站也七嘴八舌的讨论开来,一时
间,满城风雨。
ADC1我也很厚颜无耻的参加了,浩果当然能够预想,一毛钱都没摸上。回想整个过程,差距最大的并不
是在技术上,而是认知上,我们玩的产品是人家几年前玩剩下的,说创好只是一抹笑谈。
当时觉若,Google太NB了,ADC这种车马未动粮草先行的招太华丽了,就这动静,不论比出来个啥结果,
坛1千万刀也掏值了。但时过境迁,现在回头来想,也许一切并不是看上去那么美。由于没有扎扎实实的
真机摆出来,大家普遍抱着一种玩票的心理,确实敢不顾一切舍下身家性命押宝在Android上的尽在少数,
这就锻造了Android平台很长一段时间的只见雷不见雨的局面。而等喧嚣过后,很多人热情消退,Google
真端出Android真机的时候,还需要重新热场再来一次,也许,确实有些得不偿失。
逆境
所有的东西现在来说,都是事后诸葛亮,只能听个响不能行个真。而真实的状况是ADC1很快进入冏境,
由于架构设计上的种种原因,Google花了比预想多的多的时间做Android的优化工作,ADC1比赛被迫不
断延期,完全沦为懒婆娘的裹脚布。各路曾热捧Android的媒体,也不失时机的倒戈,亲手在自己画上的
感叹号后面,重重画上了个大大的问号。
祸不单.行,同样是由于Android的性能问题,尽管各路高手把Android移植到了不一致的手机平台上,但
传说中的GPhone一直难产中,使得人们不免有了胎死肢中的猜测。
与此同时,其他对手可一点也没闲着。iPhone很快宣布开放SDK,以此来勾引纯情的开发人员。Symbian
被Nokia完全收购,成为Nokia的自留地,开源计划也很快浮出水面。所有景象,对Android而言都犹如
梦魔。
破茧
所有一切逆境,都在G1公布后,慢慢消散了。2008年10月,第一款搭配Android平台的真机,搭载着
无限光荣与梦想的HTCDream正式发售,这就是注定要载入史册的G1.尽管比之当时绝代风华的iPhone,
粗陋的G1犹如村姑遇上公主通常,但不管如何,G1让人们真真切切的看到了Android。这就犹如你家买
的跳票N久的期房,终于见着了个毛胚房,那种感受,除了踏实,找不到更适合的词汇了。
好事当然也会成双,G1它不是一个人在战斗。ADC1总算是落下帷幕,AndroidMarket的也顺理成章的破
茧而出,早期的应用,大都来自于ADC1的奉献。
Android也结束了伪开源的历史旅程,正式开发SDK的源码实现,搭配的是Apache的License,这种坦
诚相见的感受看上去很不错。
忠心耿耿的HTC,更是再接再励,在G1后,陆续公布了Magic(G2)与Hero(G3)。特别是Hero的
现身,惹得一阵小惊艳,HTC为Hero搭配的是基于Android改造UI的Sense系统,以华丽的界面风格赚
足了眼球,也创了改造Android的先河。
在HTC高歌猛进的同时,猫在螳哪后的一群黄雀,也敌在动我也动了。摩托罗拉,三星,LG,华为,戴
尔,联想等一干手机厂商纷纷跟进,各式各样的Android蜂拥而至。与此同时,其他嵌入式厂商也推陈出
新,爱可视(Archos)公布了基于Android的平板设备,明基的Android上网本也是箭在弦上,而基于Android
的手持电子书阅读设备也不断的被推出,庞大的Android联盟初现峥蛛.
为了避免同质化,各个厂商纷纷对Android进行的改造,摩托罗拉推出了Cliq,打得是SNS整合牌,三星
的新系统也是被广泛期待,而中移动的OMSII媳妇也要见婆娘了,打着整合移动服务牌@_@的OMS,
以丑陋的外貌、低下的SDK版本与雷死人不偿命的宣传文案(绝口不提Android,只说自己做了大量很
NB的工作,事实上…,哎,咋就那么小家子气呢…)也算是招来大量眼球。
而还是没能耐住寂赛的Google,联手HTC,一同推出了至今只为止最重量级的Android手机:NexusOne。
江湖有云:天下武功,无快不破。推我了全新的Android2.1,1G的CPU,史上最清晰的手机屏幕的Nexus
One.快的是一塌糊涂迅雷不掩耳盗铃小叮当,在单机层面,第一次使得Android手机与iPhone掰手腕的
能力(之前与iPhone的比较,都需要依靠集团力肘,三英战吕布°
在各家厂商努力的同时,Android本身也没有闲着,版本从1.1,一步步进阶到了2.1,SDK的升级,伴随
若大量性能、接口的改进,与功能的丰富,Android变得越来越快,越来镀省电,越来越丰富,越来越多
Google服务被嵌入@_@。由于AidroidSDK是基于Java的,即便虚拟机做的很是NB,在某些情况下,
性能也是无法与原生的C++代码相提并论,因此,从1.5版起,除了SDK.Android还拥有了NDK(Native
DevelopKit),它提供了一些C++的库与编译环境(库是确实很少…〉,开发人员能够基于C++写底层库,
用Java写上层逻辑,通过混编的方式,兼得鱼与熊掌。
AndroidMarket的进展也甚为迅猛,尽管与其鼻祖AppStore相比,应用的规模与盈利能力还显得比较幼
齿,但其涨势凶猛,进展趋势远胜于前辈。国内一些比较著名的手机软件,也纷纷拥有了Android版本的
小弟,比如网易有道的出品的有道词典Android版(好吧,这是在插播广告,欢迎大家进行围观并提宝贵
意见…).
起飞
种种迹象说明,2010.也许就是姗姗来迟的Android元年。三星,moto.LG.HTC等多家手机制造厂商,
都为2010年将推出的半数以上的手机搭配了Android”在国内,移动的OPhone,丑媳妇要正式掀开盖头
了,惨烈是惨烈了一点,但聊胜于无,除了水货,2010毕竟至少多了条购买Android手机的道路.
软件开发方面,大家也从抱着双愕冷眼旁观的状态,进入到了一种何机而动的战略准备阶段。前不久召开
的moto开发者大会,惊现国内各领域的公司,试水开始,可见一斑。国内各个山寨的Market的,也越来
越货源充足,下载量稳步上升,升温,就在当下。
而随着G2为首的Android水机价格火速下调,身边路边地铁边,能够看到越来越多的人,把玩着各式各
样的Android手机,状况尤为喜人,
因此,2010,假如你有心,就做好准备吧。
【三】——组件入门
组件(Component),在谈及所谓架构与重用的时候,是一个重要的情况。很多时候都会说基于组件的软
件架构,指的是期望把程序做乐高似的,有一堆接口标准封装完整的组件放在哪里,想用的时候取上几个
一搭配,整个程序就构建完成了。
在开篇的时候就在说,Android是一个为组件化而搭建的平台,它引入所渭Mash-Up的概念,这使得你在
应用的最上层,想做的不组件化都是很困难的一件情况(底层逻辑,好吧,管不了…).具体说来,Android
有四大组件四喜丸子:Activity.Service、BroadcastReceiver.ContentProvidera
Activity
做一个完整的Android程序,不想用到Activity,确实是比较困难的一件情况,除非是想做绿叶想疯了。由
于ActMiy是Android程序与用户攵互的窗口,在我看来,从这个层皿的视角来看,Android的Activity特
像网站的页面。
首先,一个网站,假如一张页面都没有,那…,真是一颗奇葩。而一张页面往往都有个独立的主题与功能
点,比如登录页面,注册页面,管理页面,如是。
在每个页面里面,会放一些链接,已实现功能点的串联,有的链接点了,刷,跑到同一站点的另一个页面
去了:有的链接点了,啾,可能跳到其他网站的页面去:还有的推接点了,恩…,这次没跑,但当前页面
的样子可能有所变化了。这些模式,与Activity给人的感受很像,只只是实现策略不一致罢了,毕竟Android
这套架构的核心思想,本身就来自源于Web的Mash-Up概念,视为页面的客户端化,也未尝不可。
Activity.在四大组件中,无疑是最复杂的,这年头,一样东西与界面挂上了勾,都简化不了,想一想,独
立做一个应用有多少时间沦落在了界面上,就能琢磨清晰了。从视觉效果来看,一个AcWity占据当前的窗
口,响应所有窗口事件,具备有控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个界面
状态,需要做很多持久化的情况,还需要妥善管理生命周期,与一些转跳逻辑。关于开发者而言,就需要
派生一个Activity的子类,然后埋头苦干上述情况。关于Activity的更多细节,先能够参见:
reference/android/app/Activity.htnrlo后续,会献上更为详尽的剖析。
Service
服务,从最直白的视角来看,就是剥离了界面的Activity,它们在很多Android的概念方面比较接近,都是
封装有一个完整的功能逻辑实现,只只是Service不抛头露脸,只是默默无声的做坚实的后盾。
但事实上,换个角度来看,Android中的服务,与我们通常说的Windows服务,Web的后台服务又有一些
相近,它们通常都是后台长时间运行,同意上层指令,完成有关乖务的模块。用运行模式来看,Activity是
跳,从一个跳到一个,呃…,这有点像模态对话框(或者者还像web页面好了…),给一个输入(抑或者
没有…),然后不管不顾的让它运行,离开时返回输出(同抑或者没有。
而Service不是,它是等,等若上层连接上它,然后产生一段持久而缠绵的通信,这就像一个用了Ajax页
面,看着没啥变化,偷偷摸摸的与Service不知眉来眼去多少回了。
但与通常的Service还是是完全不一致的,Android的Service与所有四大组件一样,其进程模型都是能够
配苴的,调用方与公布方都能够有权利来选择是把这个组件运行在同一个进程下,还是不一致的进程下。
这句话,能够索把指甲刀刻进脑海中去,它凸显了Android的运行特征。假如一个Service,是有期望运行
在于调用方不一致进程的时候,就需要利用Android提供的RPC机制,为其部署一套进程间通信的策略.
Android的RPC实现,如上图所示(好吧,也是从SDK中拿来主义的…),无甚稀奇,基于代理模式的一
个实现,在调用端与服务端都去生成一个代理类,做一些序列化与反序列化的情况,使得调用端与服务器
端都能够像调用一个本地接口一样使用RPC接口。
Android中用来做数据序列化的类是Parcel,参见:/reference/android/os/Parcel.html.封装了序列化的细
节,向外提供了足够对象化的访问接口,Android号称实现北常高效。
还有就是AIDL(AndroidInterfaceDefinitionLanguage),一种接口定义的语言,服务的RPC接口,能够
用AIDL来描述,这样,ADT就能移梢助你自动生成一整套的代理模式锚要用到的类,都是想起来很乏力
写起来很苦力的那种。更多内容,能够再看看:guide/developing/tools/aidl.html,假如有兴致,能够找些
其他PRC实现的资料lou几眼。
关于Service的实现,还强推参看APIDemos这个Sample里面的RemcteService实现。它完整的展示了
实现一个Service需要做的情况:那就是定义好需要同苞的Intent,提供同步或者异步的接口,在上层绑定
了它后,通过这些接口(很多时候都是RPC的…)进行通信。在RPC接口中使用的数据、回调接口对象,
假如不是标准的系统实现(系统可序列化的),则需要自定义aid,所有一切,在这个Sample里都有表
达,强荐。
Service从实现角度看,最特别的就是这些RPC的实现了,其他内容,都会接近于Activity的一些实现,
也许不再会详述了。
BroadcastReceiver
在实际应用中,我们常需要等,等待系统抑或者其他应用发出一道指令,为自己的应用擦亮明灯指明方向。
而这种等待,在很多的平台上,都会需要付出不小的代价“
比如,在Symbian中,你要等待一个来电消息,显示归属地之类的,务必让自己的应用忍辱负重偷偷摸摸
的开机启动,消隐图标陷藏任务项,潜伏在后台,监控若有关事件,等待转瞬即逝的出手机会。这是一件
很发指的情况,不但白白耗费了系统资源,还留了个流氓软件的骂名,这真是实力不讨好的正面典型。
在Android中,充分考虑了广泛的这类需求,因此就有了BroadcastReceiver这样的一个组件。每个
BroadcastReceiver都能婚接收一种或者若干种Intent作为触发事件(有不明白Intent的么.后面会明白
了…),当发生这样事件的时候,系统会负责唤醒或者传递消息到该BroadcastReceiver,任其处置。在
此之前与这以后,BroadcastReceiver是否在运行都变得不重要了,及其绿色环保。
这个实现机制,显然是基于一种注册方式的,BroadcastReceiver将其特征描述并注册在系统中,根据注
册时机,能够分为两类,被我冠名为冷热插拔。所谓冷插拔,就是BroadcastReceiver的有关信息写在配
宜文件中(求配置文件详情?稍安,后续奉上…),系统会负责在有关事件发生的时候及时通知到该
BroadcastReceiver,这种模式适合于这样的场景。某事件方式->通知Broadcast。启动有关处理应用。
比如,监听来电、邮件、短信之类的,都隶属于这种模式。而热插拔,顾名思义,插拔这样的情况,都是
由应用自己来处理的,通常是在OnResume事件中通过registerReceiver进行注册,在OnPause等事件
中反注册,通过这种方式使其能筋在运行期间保持对有关事件的关注。比如,一款优秀的词典软件(比如,
有道词典…),可能会有在运行期间关注网络状况变化的需求,使其能够在彳T廉价网络的时候优先使用网
络查询词汇,在其他情况下,首先通过本地词库来查词,从而兼顾腰包与体验,一举两得一石二鸟一箭双
雕(注,其实在有道词典中有这样的能力,但不是通过BroadcastReceiver实现的,仅以为例…)。而这
样的监听,只需要在其工作状态下保持就好,不运行的时候,管你是天大的网路变化,与我何干。其模式
能够归结为:启动应用->监听事件->发生时进行处理。
除了同意消息的一方有多种模式,发送者也有很重要的选择权。通常,发送这有两类,一个就是系统本身,
我们称之为系统Broadcast消息,在reference/android/content/lntent.html的StandardBroadcastActions.
能够求到有关消息的详情。除了系统,自定义的应用能够放出Broadcast消息,通过的接口能够是
Context.sendBroadcast.抑或者是Context.sendOrderedBroadcast。前者发出的称之Normalbroadcast.
所有关注该消息的Receiver,都有机会获得并进行处理:后者放出的称作。rderedbroadcasts,顾名思义,
同意者需要按资排辈,排在后面的只能吃前面吃剌下的,前面的心情不好私吞了,后面的只能喝西北风了。
当BroadcastReceiver接收到有关的消息,它们通常做一些简单的处理,然后转化称之一条Notification.
一次振铃,一次震动,抑或者是启动一个AcWity进行进一步的交互与处理。因此,尽管Broadcast整个逻
辑不更杂,却是足够有用与好用,它统一了Android的事件广播模型,让很多平台都相形见细了。更多
BroadcastReceiver右关内容,参见:/reference/android/content/BroadcastReceiver.html..
ContentProvider
ContentProvider,听者就与数据有关,没错,这就是Android提供的第三方应用数据的访问方案。在Android
中,对数据的保护是很严密的•除了放在SD卡中的数据,一个应用所持有的数据库、文件、等等内容,
都是不同意其他直接访问的,但有的时候候,沟通是必要的,不仅对第三方很重要,对应用自己也很重要。
比如,一个联系人管理的应用。假如不同意第三方的应用对其联系人数据库进行增删该查,整个应用就失
去了可扩展力,必将被其他应用抛弃,然后另立门户,自个玩自个的去了。
Andorid当然不可能确实把每个应用都做成一座孤岛,它为所有应用都准备了一扇窗,这就是Content
Provider,应用想对外提供的数据,能锅通过派生Contentprovider类,封装成一枚ContentProvider,每
个ContentProvider都用一个uri作为独立的标识,content7/com.xxxxx..所有东西看着像REST的
样子,但实际上,它比REST更为乂活。与REST类似,uri也能够有两种类型,一种是带id的,另一种
是列表的,但实现行不需要按照这个模式来做,给你Id的url你也能修返回列表类型的数据,只要遍用行
明白,就无妨,不用苛求所谓的REST。
另外,ContentProvider不与REST一样只有uri可用,还能够同意Projection,Selection,OrderBy等参
数,这样,就能够像数据库那样进行投影,选择与排序。查闻到的结果,以Cursor(参见:
reference/android/database/Curscr.html)的形式进行返回,调用者能够移动Cursor来访问各列的数据。
ContentProvider屏蔽门内部数据的存储细节,向外提供了上述统一的接口模型,这样的抽象层次,大大
简化了上层应用的书写,也对数据的整合提供了更方便的途径。ContentProvider内部,常用数据库来实
现,Android提供了强大的Sqlite支持,但很多时候,你也能够封装文件或者其他混合的数据。
在Android中,ContentResolver是用来发起ContentProvider的定位与访问的。只是它仅提供了同步访问
的ContentProvider的接口。但通常ContentProvider需要访问的可能是数据库等大数据源,效率上不
足够快,会导致调用线程的拥塞。因此Android提供了一个AsyncQueryHandler(参见:
reference/android/content/AsyncCueryHandler.html),帮助进行异步访问ContentProvidero
在各大组件中,Service与ContentProvider都是那种需要持续访问的。Service假如是一个耗时的场景,
往往会提供异步访问的接口,而ContentProvider不论效率如何,都提供的是约定的同步访问接口。我想
这遵循的就是场景导向设计的原则,由于ContentProvider仅是提供数据访问的,它不能确信具体的使用
场受如何,会如何使用它的数据:而相比之下,Service包含的逻辑更第杂更完整,能够抉择大部分时候使
用某接口的场景,从而确定最贴切的接口是同步还是异步,简化了上层调用的逻辑.
配置
四大组件说完了,四大组件幕后的英雄也该出场了,那就是每个应用都会有一份的配置文件,名称是
AndroidManifest.xml,在工程的根目录下。在这个配置文件中,不仅会描述一些应用有关的信息,很重要
的,会包含一个应用中所有组件的信息。假如你派生Activity或者者Service实现了一个有关的类,这只是
把它组件化的第一步,你需要把这个类的有关信息写到配置文件中,它才会作为一个组件被应用到,否则
只能默默无闻的聚淡度过余生。
摆了一幅图出来,这次不是偷来的,是敝帚自珍原创,因此没有意外的画的很丑,但基本还是能够表达出
一些意思。在mothers的部分,达里是通常平台应用之间通信与交互的模型,母个应用都有很强烈的应用
边界(往往表现为进程边界…),App1的还是App2的,分得很是清晰.每个应用内部,都有自己的逻
辑去切分功能组件,这样的切分通常没有什么标准,率性而为。应用间的交互逻辑也比较零散,App1与
App2交互,往往需要明确明白对方应用的具体信息,比如进程ID.进程名称之类的,这样使得应用与应
用之间的联系,变得很生硬.而上层应用与系统应用的通信,往往有很多特定的模式,这种模式,很可能
是无法直接应用在普通应用之间的,换而言之,系统应用是有一定特殊性的。
重点,在图的下半部,描述的是Android的应用情形。在Android中,应用的边界,在组件这个层面,是
极度模糊,什么进程、什么应用,都能够不必感知到。举个例子,App1,实现了A与B两个组件,App2,
实现了C这个组件。A与C,都想使用B这个组件,那么它们的使用方式是完全一致的,都需要通过系统
核心的组件识别与通信机制,找到与使用组件B.A,虽说与B是一个娘胎里题出来的,很不好意思,没
有任何特殊的后面与捷径,还是要跑规矩的途径才能用到,一片与谐社会的景象油然而生。
在Android中,所有组件的识别与消息传递逻辑都务必依匏底层核心来进行(通信能够没有底层核心的参
与,比如一旦Service找到了,就能够与它产生持久的通信…),没有底层核心的牵线搭桥,任何两个组件
都无法产生联系。比如一个Activity,跳到另一个Activity.务必要向底层核心发起一个Intent,有底层解析
并认可后,会找到另一个AcWity,把有关消息与数据传给它。一个Activity想使用ContentProvider中的
数据,务必通过底层核心解析有关的uri,定位到这个ContentProvider,把参数传递给它,然后返回Activity
需要的Cursor.这样的设计,保证了底层核心对所有组件的绝对掌控权与认知权,使得搭积木似的开发变
成可能。
为了,使得核心系统能够完整的掌握每个组件的信息,这就需要配置文件了。配置文件,就是将组件插到
底层核心上的这个插头。只有通过这个插头插在底层核心的插座上(不要乱想,非十八禁…),组件才能
够发光发热,闪耀光芒。
组件的配置信息在我看来要紧包含两个方面,一部分是描述如何认知。比如,Activity.Service.Broadcast
Receiver都会有名字信息,与希望能够把握的Intent信息(姑且看成消息好了…),ContentProvider会
有一个描述其身份的uri。当其他组件通过这样的名字或者者Intent,就能够找到它。
另一部分是运行有关的信息。这个组件,期望怎么来运行,放在单独的进程,还是与调用者一个进程,还
是找有关的其他组件挤在同一个进程里面,这些内容,都能够在配置的时候来决定(调用者在这个约束范
围内,有进一步的选择权…)。更多配置项,请参见:guide/topics/manitest/manifest-intro.htmL
通过前续内容,也许能够帮助大家对Android组件有个初略的熟悉。但这些熟悉都还停留在岸态层面,程
序是个动态的概念,关于各个组件具体是怎么联系在一起的,如何手拉手运行起来完成一项功能的,这便
是后话了。
【四】——组件调用
Intent解析
基于组件的架构体系,除了有定义良好的组件,如何把这些组件组装在一起,也是一门艺术。在Android
中,Intent(貌似通常译作:意图…),就是连接各组件的桥梁。
前段时间看同再们做Symbian平台的网易掌上邮(确实是做的用心,NB的一米,热情欢迎所有163邮箱
的S60v3用户,猛点击之…),有个功能是为邮件添加附件,比如你想要通过邮件发送一副图片泡mm,
可能需要有个很直观的方式从本地选一副珍藏美图,抑或者是拿相机来个完美自拍。在Symbian中,这样
的功能,都需要你用底层的API.自己一点点写.为了让选图片体验更好,可能需要做一个类似于图片浏
览器之类的东西,为了把拍照做的更为顺畅,甚至需要实现从聚焦到调,亮度之类一整套的相机功能。
而事实上呢,用户的手机中可能本身就装了其他的专业图片浏览器、相机等应用,这些应用已经非常出色
好用,而用户也已然能很纯属使用它们,假如能进行调用,对邮箱的开发者与用户而言,都会是个更好的
选择。但在Symbian这样残败的系统里,应用与应用之间的结合能力奇弱无比,想且用,基本比登天还难,
作为开发者,只能忍住一次又一次的恶心,为了用户,做这些重豆造轮子吃力不讨好的附加工作。
还好还好,在Android中,一切变得美好多了,它将开发者从接口与对象的细节中拯救出来,让我们有更
多精力投入到核心功能的开发中去。在Android中,假如你需要选个图并个片,只病要构造一个描述你此
项意愿的Intent,发送出去,系统会帮你选择一个能够处理该项业务的组件来满足你的需求,而不再需要
纠结在具体的接口与实现上,PerfectWorld.便应如此。
Intent构成
Iniern破译作意图,事实上述是很能传神的,imen1期望做到的,就是把实现行与蜩用行完全解耦,调用者
用心将以意图描述清晰,发送出去,就能够梦想成真,达到目的。
当然,这么说太虚了,庖丁解牛,什么东西切开来看看,也许就清晰了。Intent
(reference/android/content/lntent.html),在Android中表现成一个类,发起一个意图,你需要构造这样
一个对象,并为下列几项中的一些进行赋值:
Action»当日常生活中,描述一个点愿或者愿望的时候,总是有一个动词在其中。比如:我想做三个俯卧
擦:我要看一部x片:我要写一部血泪史,之类云云。在Intent中,Action就是描述看、做、写等动作的,
当你指明了一个Action,执行者就会依照这个动作的指示,同意有关输入,表现对应行为,产生符合的输
出。在Intent类中,定义了一批量的动作,比如ACTIONVIEW.ACTIONPICK,之类的,基本涵盖了
常用动作,整一个降龙十八掌全集。当然,你也能够与时供进,制造新的动作,比如lou这样的。与系统
预定义的相比,这些自定义动作的流通范围很是有限,除非做了非常NB的应用,大家都需要follow你,
否则通常都是应用内部流通。
Data.当然,光有动作还是不够的,还需要有更确切的对象信息。比如,同样是泡这个动作,但泡咖啡,
与泡妞,就差之千里了。Data的描述,在Android中,表现成为一个URI。用在内部通信中,可能描述是
ContentProvider用的形如conteni://xxxx这样的东东,抑或者是外部的一个形如tel://xxxx这样的链接。
总而言之,是能够清晰准确的描述一个数据地址的uri..
Typeo说了Data,就务必要提Type,很多时候,会有人误解.觉若Da匕与Type的差别,就犹如泡妞与
泡马子之间的差别一样,微乎其微。但再实上不然,Type信息,是用MIME来表示的,比如text/plain,
这样的东西。说到这里,两者差别就很清晰了,Data就是门牌号,指明了具体的位置,具体问题具体分析,
而type,则是强调物以类聚,解决一批量的问题。实际的例子是这样的,比如,从某个应用拨打一个电话,
会发起的是action为ACTIONDIAL且data为tel:xxx这样的Intent.对应的人类语言就是拨打xxx的电话,
很具象。而假如使用type.就宽泛了许多,比如浏览器收到一个未知的Mlh/E类型的数据(比如一个视频...),
就会放出这样的Intent,求系统的其他应用来帮助,表达成自然语言应该就是:查看pdf类文档,这样的。
Category。通过AcHon,配合Data或者Type,很多时候能够准确的表达出一个完整的意图了,但也会有
些时候,还需要加一些约束在里面才能够更精准。比如,假如你尽管很喜欢做俯卧拣,但一次做三个还只
是在特殊的时候才会发生,那么你可能表达说:每次吃撑了的时候,我都想做三个俯卧撑。吃掾了,这就
对应若Intent的Category的范晒,它给所发生的意图附加一个约束。在Android中,一个实例是,所有应
用主Activity(就是单独启动时候,第一个运行的那个Activity…),都需要能够同送一个Category为
CATEGORY_LAUNCHER,Action为ACTION_Maln的意图。
Component.在此之前,我们企图用Action.Data/Type,Category去描述一个意图,这是Android推荐,
并期望大家在大多数时候使用的,这样模式在Android中称做ImplicitIntents.通过这种模式,提供一种足
活可扩展的模式,给用户与第三方应用一个选择权.比如,还是一个邮箱软件,他大部分功能都好,就是
选择图片的功能做的很土,怎么办?假如它使用的是ImplicitIntents,那么它就是一个开放的体系了,手机
中没有其他图片选择程序的话,能够继续使用邮箱默认的,假如有,你能够任意选择来替代原有模块完整
这功能,一切都自然而然。但这种模式,也不是没有成本,需要付出的是一些性能上的开销,由于华竟有
一个检索过程。因此,Android提供了另一种模式,叫做ExplicitIntents,就需要Component的帮助了。
Component就是类名,完整的,形如com.xxxxx.xxxx,一旦指明了,一切都清晰了,找的到这个类(当然
会是一个特定的子类…),成功,反之,失败。这个好处,自然是速度,适合在你明确明白这就是一个内
部模块的时候,使用它。
Extras.通过上面的这些项,识别问题,基本完美解决了,剩下一个重要的问题,就是传参。Extras是用
来做这个情况的,它是一个Bundle类的对象,有一组可序列化的key/value对构成。每一个Action,都会
有与之对应的key与value类型约定,发起Intent的时候,需要按照要求把Data不能表示的额外参数放入
Extras中(当然,假如不需要额外附加参数,就算了…),否则执行者拿到的时候会抓狂的。
Flags..能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。
顾名思义,Flags是一个整形数.有一些列的标志位构成,这些标志,是用来指明运行模式的“比如,你
期望这个意图的执行者,与你运行在两个完全不一致的任务中(或者说进程也无妨吧…),就需要设岂
FLAG_ACTIVITY_NEW_TASK的标志位。
有了上述这些,一个Intent的形象就跃然纸上了,如此丰富的内容,决定了它比传统的模式,都来得强大。
Intent匹配
上次在motodev上,听人做Android的讲座,下面有很多听客都对Intent这个概念表示出了强烈的兴趣,
拿出自己熟悉领域的各类概念进行类比,比如事件、消息之类。当时我在想,Intent作为组件间的通信协
定,与通常的简单的通信方式不一一致,首先,从前面部分能够看到,它的描述是针对需求而不是实现者来
进行的。其次,它的解析是依托第三方而不是两方直接进行.
这个概念与设计模式中的中介模式(MediatorPattern)是一脉的,即所有的外围组件,都只与系统的核心
模块发生联系,通过它进行中转,组件之间不直接勾搭。
如上图所示,要想跑通整个流程,另一个很重要的东西,就是IntentFilters,它是用来描述一个Activity或
者Serveice等组件,期望能够响应怎么样的Intent。假如一个组件,只希望别的组件通过ExplicitIntents
(就是指明Component...)的方式来找到它,那么就不需要添加IntentFHters,反之,一定需要一个或者
若干个IntentFilters。IntentFHter的各个项,犹如Intent照镜子过来的效吴,包含Action,Catagory.Data,
Type等。
IntentFilters能够写到配置文件中,与那些组件的配理一起(不记得什么是配置文件了,能够看这里…),
若干的实例能够在Intent介绍页面上找到(reference/android/content/lntent.html)»同样,IntentFilters
能够在代码中,动态插拔,这个是与动态插拔的BroadcastReceiver是配套使用的。
系统核心的模块,会负贵收集这些IntentFHters,与它们对应的组件信息。当请求者需要一个组件帮忙,
并构造了描述它需求的Intent发送到系统核心,系统核心会将其与已知的各个IntentFilters进行匹配,选
择一个符合需求的组件返回。假如有多个符合的,会尝试看看是否具有对认执行的,假如没有默认的,就
会构造UL让用户帮助抉择,如是,整个流程就跑通了。
Intent实现
上图,是请求一个Activity组件的简单实现流程图,算是用的最多的Intent解析实例。流程从调用
Context.startActivity(lntent)开始,调用者传入构造好的Intent对象,然后流程会让实际的执行者,是
Instrumentation对象来完成。它是整个应用激活的Activity管理者,集中负责该应用内所有Activity的起承
转合生离死别。它有一个隐藏的方族execStartActivity方法,就是负责根据Intent启动Activity的。去掉一
些细节,它做得最重耍的情况,就是将此调用,通过RPC的方式,传递到ActivityManagerService。
前面一直再说,系统核心层,事实上这里所谓的系统核心层,就是负责Android一些关键事务的一组服务。
它们同样运行在虚拟机上,与普通的Service实现机理是一致的,只只是它们不抛头露脸只是默默的在下
层服芬,故谓之核心嘛。AcitlvityManagerServlce.是负责AciMiy倜度的朦务,也许日后提及倜度细节的
时候还会有涉及。
在这里,AcitivityManagerService会分两个步骤完成有关操作,首先把Intent递交给另一个服务
PackageManagerService.此服务掌握整个软件包及其各组件的信息,它会将传递过来的Intent.与已知
的所有IntentFilters进行匹配(假如带有Component信息,就不用比了…),找到了,就把有•关Component
的信息通知回AcitivityManagerService.在这里,会完成启动Activity这个很多细节的情况。
由此可知,启动Activity,要通过多个服务的处理,并不是非常轻量的过程,在Android随机文档介绍性能
的一节中,对此有一个评估。但这样的操作不是会放在循环里反复折磨的那种,因此整体效果与其付出的
性能代价相比,觉得是物超所值的。
【五】——任务与进程
关于Android中的组件与应用,之前涉及,大都是静态的概念。而当一个应用运行起来,就难免会施耍关
心进程、线程这样的概念。在Aneroid中,组件的动态运仃,有一个最与众不一致的概念,就是lask,翻
译成任务,应该还是比较顺理成章的。
Task的介入,最要紧的作用,是将组件之间的连接,从进程概念的细节中剥离出来,能够以一种不一致模
型的东西进行配置,在很多时候,能够简化上层开发人员的懂得难度,帮助大家更好的进行开发与配置。
任务
在SDK中关于Task(guide/topics/fundamentals.html#acttask),有一个很好的比方,说,Task就相当
于应用(application)的概念。在开发人员眼中,开发一个Android程序,是做一个个独门独户的组件,
但关于通常用户而言,它们感知到的,只是一个运行起来的整体应用,这个整体背后,就是Task:
Task,简单的说,就是一组以栈的模式聚集在一起的ActMty组件集合。它们有潜在的前后驱关联,新加
入的ActMty组件,位于栈顶,并仅有在栈顶的Activity,才会有机会与用户进行交互。而当栈顶的Activity
完成使命退出的时候,Task会将其退栈,并让下一个将跑到栈顶的Activity来于用户面对面,直至校中再
无更多Activity.Task结束。
事件Task栈(粗体为栈顶组件)
点开Email应用,进入收件箱(ActivityA)A
选中一封邮件,点击查看详情(AdivityB)AB
点击回豆,开始写新邮件(ActivityC)ABC
写了几行字,点击诜桂联系人,讲入造林联系人界面(ActMtyD)ABCD
选择好了联系人,继续写邮件ABC
写好邮件,发送完成,回到原始邮件AB
点击返回,回到收件箱A
退出Email程序null
如上表所示,是一个实例。从用户从进入邮箱开始,到回复完成,退出应汨整个过程的Task栈变化。这是
一个标准的栈模式,关于大部分的状况,这样的Task模型,足以应付,但是,涉及到实际的性能、开销等
问题,就会变得残酷许多。比如,启动一个浏览器,在Android中是一个比较繁重的过程,它需要做很多
初始化的工作,同时会有不小的内存开销。但与此同时,用浏览器打开一些内容,又是通常应用都会有的
一个需求.设想一下,假如同时有•十个运行者的应用(就会对应若是多个Task),都需要启动浏览器,这
将是一个多么残酷的场面,十个Task栈都堆积若很雷同的浏览器Activity,是多么华丽的一种浪费啊.因
此你会有这样一种设想,浏览器Activity.可不能够作为一个单独的Task而存在,不管是来自那个Task
的请求,浏览器的Task,都不可能归并过去。这样,尽管浏览器ActMty本身需要维系的状态更多了,但
整体的开销将大大的减少,这种舍小家为大家的行为,还是很值得歌颂的。
如此值得歌颂的行为,Android当然会举双手支持的。在Android中,每一个Activity的Task模式,都是
能够由Activity提供方(通过配置文件…)与Activity使用方(通过Intenl中的flag信息…)进行配置与选
择。当然,使用方对ActMty的操纵力,是限定在提供方同意的范畴内进行,提供方明令禁止的模式,使用
方是不能够越界使用的。
在SDK中(guide/topics/fundamentals.html#acttask),将两者实现Task模式配置的方式,写的甘常清
晰了,我再很絮叨选择一些来解释一下(完整可配置项,一定要看SDK,下面只是其中常用的若干项…)。
提供方对组件的配置,是通过配置文件(Manifest)〈activity,项来进行的,而调用方,则是通过Intent时
象的flag进行抉择的。相关于标准的Task栈的模式,配宜的要紧方向有两个:一则是破坏已有枝的进出
规则,或者样式:另一则是开发新Task栈充成本应在向一Task栈中完成的任务。
关于应用开发人员而言,〈activity〉中的launchMode属性,是需要经常打交道的.它有四种模式:"standard”,
"singleTop","singleTask","singleinstance".
standard模式,是默认的也是标准的Task模式,在没有其他因素的影响下,使用此模式的Activity,会构
造一个Activity的实例,加入到调用者的Task栈中去,关于使用频度通莒开销通常什么都通常的Activity
而言,standard模式无疑是最合适的,由于它逻辑简单条理清晰,因此是默认的选择。
而singleTop模式,基本上于standard一致,仅在请求的Activity正好位于栈顶时,有所区别。如今,配
也成singleTop的Activity,不再会构造新的实例加入到Task栈中,而是将新来的Intent发送到栈顶Activity
中,栈顶的Activity能够通过重载onNewIntent来处理新的Intent(当然,也能够无视…)。这个模式,降
低了位于栈顶时的一些重复开销,更避免了一些奇异的行为(想象一下,假如在栈顶连续几个都是同样的
Activity.再一级级退出的时候,这是怎么样的用户体验…),很适合一些会有更新的列表Activity展示。一
个活生生的实例是,在
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宜昌市地理信息和规划编制研究中心招聘专业技术人员笔试真题及答案
- 2025年丽水市市级机关遴选公务员考试试卷真题
- 胃癌诊断性腹腔镜探查专家共识总结2026
- 2026年小学六年级语文第二学期期末考试卷及答案(十四)
- 经络腧穴精准定位
- 2021年聚醚行业研究报告
- 幼儿园中班科学教案《旋转的纸片》
- 译林版英语六年级下册Unit 8 Our dreams SoundSong cartoon time
- (2026年)校园欺凌的预防和处理制度范本
- 心理治疗师规范化培训与督导
- 2026年春季学期人教版小学数学五年级下册期末质量检测卷含答案
- 2026年湖南长沙新奥燃气有限公司社会招聘5人考试参考题库及答案解析
- 2026年安全生产月知识竞赛试题(7套完整版 含答案)
- 2026年全国安全生产月主题培训
- 2025年江苏省中考道德与法治试题及答案解析
- 2026年4月自考07816公共行政学试题及答案含评分参考
- 放射性肠炎治疗管理
- (正式版)JJD 008-2026 房屋建筑和市政基础设施工程安全管理资料导则(试行)
- 物理教学方法交流
- 2026年二级建造师之二建机电工程实务真题含答案详解
- 医师重新执业注册申请审核表
评论
0/150
提交评论