Android真正独特的地方在于它允许多个任务同时运行。由于开发者们来自不同的平台,对这样的运行机制可能会感到惊讶。深入理解它的行为对你的应用程序设计是很重要的,因为这样可以无缝的(seamlessly)集成到android的其他版本/平台。本文涵盖了android多任务设计的原因,和它是怎样影响(impact on)你的应用程序工作的以及你要怎样才能最好的发挥出android的优势特色。

设计要素

移动设备有技术局限性,并且用户体验需求不同于桌面或web系统。下面是我们设计android多任务时的4个关键的约束条件(constraints):

我们不想要求用户在“完成”的时候关闭程序。那样的使用模式(指完成后立即关闭程序)在移动(mobile)环境工作的不是很好,特别是每天都要大频率反复使用的程序。

移动设备没有那么奢侈(luxury)的交换空间(指的内存RAM),在内存使用上又有很严格的限制。Robert Love(此人写了很多linux的书籍,本人有一本《linux系统编程》)写过一篇关于本主题的非常好的文章。

应用程序在移动设备上切换启动(switching on)是极其受到挑剔的,我们的目标是显著的减少到少于1秒钟来启动一个新的程序。当用户在很少的程序中切换时,这点尤为重要,比如说当观看视频时切换出来查看一个条新短信,然后再退回观看视频。一个显而易见的(noticeable)等待在此种状况下会很快引起用户对你的憎恨。

可用的API对编写内置的Google应用程序来说应该必须足够(be sufficient for),这也是我们的“所有程序生来平等”哲学的一部分。这就是说后台的音乐播放,数据同步,GPS导航,应用下载等必须可以让第三方开发人员用同样的API来实现。

前两点需求强调了一个有意思的冲突(conflict)。我们并不是要让使用者担心关闭他们的应用,宁可让所有的应用一直运行着。但同时,移动设备的内存使用却很有限,以至于系统会降低性能或者当它需要比可用更多的RAM时,很快就启动失败,而台式电脑,可以交换(指空间),相比起来就很简单的启动(运行)缓慢,来用页面RAM交换空间。这些相互矛盾的约束就成了android设计的动机。

什么时候应用程序“停止”呢?

一个Android多任务普遍的误解是关于一个进程(process,也可以译为程序)和一个应用(application,也可以译为程序)之间的不同之处。在Android中这两者并不是紧密联系的一个实体:应用出现在用户面前可能并不需要实际的进程运行在程序中;多个应用可以共享同一个进程,或者一个应用可能使用多个进程,这些都取决于你是否需要;当应用并不积极的做什么事情的时候,它的进程就会由Android保存。

实际上你看一个应用的进程“运行”不是说这个应用在运行或做什么事情。它简单的在那里可能只是因为Android在某些时候需要它,并且让它最好还是在那里因为可能还要再次需要它。同样地,你可能会离开一个应用一会儿,并从停止的地方回来,在这段时间,Android可能需要取消(get rid of)进程的其他事情。

Android此时处理应用的一个关键是进程不会干净的关闭。当用户离开一个应用程序,它的进程一直在后台存在着,如果需要的话,允许它继续运行(例如下载网页),当用户返回的时候能够立刻回到前台。如果一个设备不出现内存溢出的话,Android将保证所有的进程都在,真正的让所有应用永远“运行”。

当然,这里有个内存的限制,为了解决(accommodate)这个问题,Android必须决定何时移除不再需要的进程。这引出了Android进程的生命周期,这个规则用来决定每个进程的重要程度,哪些进程需要被抛弃。这些规则基于两点,一个是用户当前使用中的进程的重要级别,另一个是进程从上次用户需要到现在经过了多长时间。

一旦Android决定要移除一个进程,它会残忍的(brutally)、简单的强制杀掉它。内核会立刻回收再利用(reclaim)进程的所有资源,不需要应用程序良好的编码和礼貌的响应退出请求。允许内核立即回收再利用资源就可以很容易避免一系列的内存溢出问题。

如果一个用户要回到一个程序,而这个程序恰巧被杀掉了,Android需要一种途径重新加载它并回到最后看到的状态,来保持“所有的程序永远运行”的用户体验。通过记录(is keep track)用户知道(is aware of)的程序的一部分(activity)的信息,就是他们看到的最后状态,重新启动它们。这里说的最后的状态是指用户离开程序时的状态,并不是它被杀掉时的状态,所以内核不用依赖程序在某一点的正确响应而自由的杀掉它。

有些情况,Android的进程管理可以看作为是某种形式的空间交换:程序的进程代表一定数量的(a certain amount of)在用内存;当内存过低时,杀掉一些进程(交换出去);当又需要那些进程时,它们可以从最后的状态重新启动(交换进来)。

明确地运行在后台

到目前为止,我们有一种不明确的方法令程序运行在后台,就是只要求进程不被Android的内存管理部分杀掉。这对于像在后台加载网页等任务还行,如果有更高的要求怎么样?比如后台播放音乐,数据同步,定位、闹钟等。

对于这些任务,应用程序需要一种途径来告诉Android“我在这一点上要明确的运行”。这里有两种主要的设施可用来为应用程序解决此问题,它们以两种组件为代表,广播和服务,可以在它们的清单中(manifest)注册。

广播接收器

广播接收器允许一个应用程序运行,在短暂的时间里,在后台处理一些发生的事情。它可以用多种途径来构建高级别的设施:例如警告管理器允许程序在未来某个时间发送一个广播,位置管理器可以在发现一个感兴趣的位置变化时发送一个广播。因为接收器的信息是程序清单(manifest)的一部分,Android可以在这个程序没有运行时找到并加载它;当然,如果它的进程在后台可用,广播就可以高效的直接投递给它。

在处理广播时,程序会给定一个允许它工作的时间(当前是10秒钟)。如果在这个时间内没有完成,程序就会被认为是违反规定的(misbehaving),它的进程会立即被扔到(tossed)后台状态,当内存需要时被杀掉。

广播接收器擅长做一些需要响应外部刺激的工作,例如发送一个新的GPS位置报告后给用户发布一个通知。在程序的进程因接收广播而露面后,它们就变成了非常轻量级的。因为它们是再特定的时间活动,有很强的保证在它们运行时进程不会被杀掉。然后这并不适用于(appropriate for)一些不确定时间的情况,如网络。

服务

服务允许应用程序实现长时间的后台操作。当然了,事实上服务也提供了很多其他方法,但这里我们讨论的是服务的最基本目的,一个应用程序说“嗨,我想要持续运行我的程序在后台,直到我说我完成了。”应用程序控制服务的运行,通过明确的启动和停止它。

当服务提供富客户服务器模型时,使用它是可选择的。一旦启动了程序的服务,Android就会实例化这个组件并在程序的进程中提供上下文。在这之后如何使用取决于程序:它可以在服务中放入所有需要的没有和程序的其他部分交互的代码,在其他单例(singleton)对象共享给程序的其他部分调用,直接恢复服务实例在其他需要的地方,或者在另一个进程中运行并在需要时做一个完全的(full-blown)远程过程调用(rpc)。

服务的进程管理与广播接收器的不同,因为不清楚数量的服务可以运行未知长度的时间。这里可能没有足够的RAM来满足服务运行的要求,所以不能够强烈保证它们能够永久运行。

如果只有特别少的RAM,进程维护的服务会像后台进程一样立即被杀掉。然而,如果合适的话,Android会记下那些愿意继续运行的服务,在有足够RAM后再重新启动它们的进程。例如,如果用户使用网页需要大量的RAM,Android会同步的杀掉后台服务进程直到浏览器对内存的需求降低。

服务可以更深层次的讨论它们被认为是“前台”的行为。这里服务就处在一个“请不要杀掉我”的状态,但是这需要它包含一个给用户的积极运行的通知。这对于后台播放音乐或车载导航的服务非常有用,因为用户知道(aware of)这些;当你播放音乐和使用浏览器时,你可以经常在状态栏上看到音乐播放的标记(glyph)。Android不会尝试去杀掉这些服务,不过作为一种交换(trade-off),要保证用户知道它们并且可以在需要时明确的停止。

通用组件的值

Android的通用的广播接收器和服务组件允许开发者创建一个广泛的多种多样的有效后台操作,包括一些最初从没有考虑过的事情。在Android 1.0,它们被用来实现近乎所有内置的后台行为和所有的Google应用:

音乐播放运行在服务中,当用户离开音乐程序时允许继续对其进行操作。

闹钟通过闹钟管理器安排一个广播接收器,在下一次设置时间响起(go off)。

日历程序同样地(likewise)在下一个日历事件中安排一个闹钟在适当时间来显示或更新它的通知。

当进程中有下载时,后台文件下载通过服务来实现。

电子邮件程序安排一个闹钟每隔一段时间或由新邮件到来时来唤醒一个服务。

Google应用程序维护一个服务来接收网络上的通知,并依次(in turn)发送广播给那些需要做工作的单独的程序比如同步联系人。

随着平台的演化,这些基本的组件用来实现很多重要的新的开发特性:

输入法被开发者用服务组件来实现了,Android管理和使用其为当前的输入法。

程序的widget(窗体小部件)是广播接收器,当其需要交互时,Android就给它发送一个广播。这需要widget很轻量级的,并不需要它的程序进程一直保持运行。

可接入特性(Accessibility features)是用服务实现的,使用时由Android维持运行并发送适当的用户交互的信息。

同步适配器是在Android2.0中引入的,它是运行在后台的服务,当特殊的数据同步需要时被执行。

活动壁纸是一个服务,当被用户选择时就会被Android启动。

转载于:https://blog.51cto.com/515632/714710

Android的多任务之路相关推荐

  1. 初学者必读Android开发入门之路

    初学者必读Android开发入门之路 [IT168评论]本人一直致力于嵌入式相关知识和技术在中国大陆地区的技术传播及嵌入式产品及移动设备的系统和应用程序开发,近两年主要专注于3G技术领域,重点是研究A ...

  2. android 关于多任务下载问题

    关于多任务下载问题 近期项目中,遇到一个问题,列表数据中的图片地址是一个需要下载JS再解析的字段,之前的图片下载是一个异步的过程,由一个队列处理. Android系统以不同寻常的方式处理多个应用程序的 ...

  3. android开发学习之路——连连看之游戏逻辑(五)

    GameService组件则是整个游戏逻辑实现的核心,而且GameService是一个可以复用的业务逻辑类. (一)定义GameService组件接口 根据前面程序对GameService组件的依赖, ...

  4. android底层重构,【理论】【转】Android项目重构之路:实现篇

    前两篇文章Android项目重构之路:架构篇和Android项目重构之路:界面篇已经讲了我的项目开始搭建时的架构设计和界面设计,这篇就讲讲具体怎么实现的,以实现最小化可用产品(MVP)的目标,用最简单 ...

  5. [总]Android高级进阶之路

    个人Android高级进阶之路,目前按照这个目录执行,执行完毕再做扩展!!!!! 一.View的绘制 1)setContentView()的源码分析 2)SnackBar的源码分析 3)利用decor ...

  6. Android SurfaceFlinger 学习之路(五)----VSync 工作原理

    原址 VSync信号的科普我们上一篇已经介绍过了,这篇我们要分析在SurfaceFlinger中的作用.(愈发觉得做笔记对自己记忆模块巩固有很多帮助,整理文章不一定是用来给别人看的,但一定是为加强自己 ...

  7. Android Studio强者之路-刘桂林-专题视频课程

    Android Studio强者之路-9395人已学习 课程介绍         Google为Android Developer量身定做的一款IDE,很值得大家去学习,而本系列视频从浅到深,一步步带 ...

  8. android开发用百度识别图片格式,Android开发学习之路-机器学习库(图像识别)、百度翻译...

    对于机器学习也不是了解的很深入,今天无意中在GitHub看到一个star的比较多的库,就用着试一试,效果也还行.比是可能比不上TensorFlow的,但是在Android上用起来比较简单,毕竟Tens ...

  9. 厚积方能薄发,通往Android封神之路的降龙十八掌

    前言 最近部门招聘,包括我在内都参与了内推和面试的过程,经过这次招聘,发现很多刚出步入职场的小白们,对于职业规划和成长路径不是很清晰,普遍的感觉入门容易,却对未来比较迷茫,不知道自己技能该怎么提升,到 ...

最新文章

  1. 引用 vsftpd配置手册(实用)
  2. 第一个C#控制台程序
  3. 唯品会 1000+ 台 Hadoop 集群优化经验
  4. Object category automatic search
  5. 【计算机网络】整体体系结构
  6. 【剑指offer】_08.数值的整数次方
  7. 低压电力采集平台DW710C与PC沟通
  8. Linux下通配符总结
  9. 艾宾浩斯记忆表格excel_考研干货 | 如何使用艾宾浩斯曲线帮助记忆知识
  10. 使用Python爬取mobi格式电纸书
  11. 毕啸南专栏 | 对话姚星:腾讯有后来居上的传统,我们的战略是全民AI
  12. java sleep和wait的区别和联系
  13. Zotero英文翻译插件安装教程
  14. 【VMware】vmware15 安装win10教程【史上最详细图文教程】
  15. 单片机自学需要买开发板嘛?初学者如何使用单片机开发板?
  16. 真假马云Deciphering Jack Ma
  17. 预测股票涨跌看什么指标,如何预测明天股票走势
  18. c语言列出最简真分数序列,C语言实例 列出真分数序列
  19. 如何获取excel 中的 某几个列的值
  20. Opegnl ES之四边形绘制

热门文章

  1. VTK:PolyData之PolyDataCellNormals
  2. VTK:网格之ClipFrustum
  3. VTK:图片之ImageToStructuredPoints
  4. C语言圈排序Cycle Sort算法(附完整源码)
  5. C++递增运算符重载
  6. php+curlmultiinit_多线程 - PHP的curl_multi_init并发测试问题
  7. 利用python对微信云数据库_如何用python看看女神的微信百度云里面有啥?
  8. 【转】Docker 运行时资源限制-内存memory、交换机分区Swap、CPU
  9. C语言二分查找法(指针和数组实现)
  10. jbpm_工作流框架笔记