Android 四大组件全解读

为了达到这一点,我们将一个APP的main方法分解成几种系统可以与之交互的形式。这几种形式就是Activity,BroadcastReceiver,ServiceContentProvider APIs,广大的Android开发者都很熟悉它们。

这些类好像在告诉你,你的APP内部应当怎样工作,但这是一种误解!事实上,这些类只是定义你的APP需要怎样与系统交互(以及系统怎样协调你的APP与其他APP进行交互)。这种与系统的交互一旦开始,系统就不再关心你的APP内部是怎样运行了。

为了更好地说明这一点,让我们简要地看看这些APIs对于Android系统来说到底意味着什么。

Activity


这是一个APP与用户交互的入口。从系统的角度看,系统为Activity提供的关键交互动作是:

  1. 持续跟踪用户当前正在关心的(也就是显示在屏幕上的东西),以确保当前进程保持运行。

个人理解:这里,作者实际上的含义是,当你的应用被系统从Activity启动时,在Activity的start与stop状态之间,系统会确保这个Activity始终占据着设备的屏幕,并且确保你的应用绝不会被系统杀死。这是你从Activity启动自己的APP时,系统给予你的APP的一种承诺(just a promise)。

  1. 知道那些之前使用过的进程,这些进程包含着用户可能会返回获取的东西(stopped activities),并因此给予这些进程更高的优先级。

  2. 帮助应用处理进程被杀死的情况,以便用户能够返回到之前的activities,并且这些activities能够加载自己之前的状态

个人理解:很显然,系统所承诺的这种状态恢复能力,是依靠ActivityonSaveInstanceStateonRestoreInstanceState方法,也就是说,你在Save方法中保存好你想在进程被杀死时想要保存的Activity状态,然后你就可以在Restore方法中获取这些状态以恢复Activity。当你把这些做完后,剩下的就是系统的事情了,系统会承诺,如果由于内存压力杀死了你的Activity所在的进程,那么当你返回时,系统会重建你的应用进程,并帮助你恢复之前Activity的状态。

  1. 提供一种在不同应用之间的用户流(user flow)的方式,当然这要靠系统来协调。最经典的例子就是分享功能的实现。

对于Activity来说,系统并不关心的是:

一旦系统从Activity入口进入到你的APP UI之中,系统将不再关心Activity内部逻辑的组织。你可以将所有的应用逻辑全放入这一个Activity中,比如你可以手动地改变它的views,使用fragments或者其他框架,你也可以把你的应用逻辑分拆成额外的内部activities。你也可以三者同时使用(指的是改变views,使用fragemnts,分拆成额外的activities)。这些事情系统是毫不关心的,只要你遵循Activity与系统之间的约定(在适当的状态下启动它,正确地保存/恢复它的状态)。

BroadcastReceiver


这是一种让系统在正常的用户流(user flow)之外,传递事件给APP的机制。最重要的是,因为这是另一个被精心定义的APP的入口,即使APP当前并不在运行,系统也可以将broadcasts传递给APP。所以,举例来说,一个APP可以提前调度一个alarm,以便通知用户一个马上到来的事件,通过将这个alarm传递给该APP的一个BroadcastReceiver,在alarm发生之前,APP都没必要运行。

对于BroadcastReceiver来说,系统并不关心的是:

在APP内部分发事件是一个与BroadcastReceiver接收事件完全不同的事,不管你是使用一些eventbus 框架,实现你自己的回调系统,还是任何其他方法…你都没有理由使用系统的广播机制,因为你并不是在App之间分发事件

事实上,不使用系统的广播机制还有一个很好的原因,这会带来许多不必要的负担,而且使用全局广播机制来实现APP内部的事件分发会引发许多安全问题 。

当然,我们也提供了一个LocalBroadcastManager便利类,它实现了一个纯粹的进程内的intent分发系统,而且它的API与系统BroadcastReceiver API很相似,如果你喜欢当然也可以使用。但再次强调,你没有理由在仅仅发生在APP中的事情上使用BroadcastReceiver机制

Service


当由于各种各样的原因需要APP在后台运行时,Service就是一个这样的入口。有两种语义上截然不同的Services(一种是Started Service,一种是Bound Service)来告诉系统怎样管理一个APP。

Started Service就相当于因为某种原因你的APP告诉系统:“系统大哥,我有事要干,请让我一直运行,直到我告诉你我干完了。”(这里的我相当于APP,因为此时的Service就代表了APP,而系统是只跟APP对话的)这里的“事”可能是在后台同步数据或者在用户离开APP后播放音乐。

同时,Started Service又有两种,一种是用户可感知的,一种是用户无法感知的。这两种不同的Started Service会让系统对它们采取不同的管理方式。

  1. 播放音乐的Service是用户可以直接感知的,所以Service会对系统说:“我想成为前台(foreground),并且在通知栏挂一个通知,让用户能够感到我的存在。”这种情况下,系统知道,必须使出吃奶的劲保证这个service进程的运行,因为如果这个进程宕掉,用户会不高兴。

  2. 另一种后台Service是用户无法直接感知的,所以系统可以更加灵活地处理这个Service的进程。在系统急需RAM以保证用户眼前的事情正常运转时,系统可能会允许该进程被杀死(然后可以在之后有能力时再启动该Service)。

Bound Service 之所以会运行,是因为其他APP或者系统要使用它。通常情况该Service都会给其他进程提供一个API。在这种情况下,系统知道这两个进程之间存在一个依赖关系。所以,如果进程A绑定了进程B中的一个Service,系统就会知道,它要为进程A保证进程B和它里面的Service正常运行。进一步讲,如果进程A是用户当前正在关心的进程,系统将知道把进程B也当作用户正在关心的进程。

由于Service的灵活性(有好也有坏),Service已经成为各种类型的系统中一个非常有用的构建块(building block)。实时墙纸,通知监听器和许多其他的系统核心特性都被构建为Service,当它们需要运行时,系统再绑定它们。

对于Service,系统不关心的是:

Android不关心你的APP中那些不影响它怎样对待你的进程的事,所以这些情况下,是没有理由使用Service的。举例来说,如果你想在后台为你的UI下载数据,你不应该使用Service来做这件事----做这些事时,不告诉系统保持你的进程运行真的是很重要的,因为确实没有必要!!这样做也让系统有更多的自由去管理你的进程,以便与用户正在做的事情相协调(注:可以让系统在内存紧急的情况下,杀死你的进程,优先保证用户正在做的事情,这里忍不住吐槽一句:每个APP肯定都会觉得自己是最重要的哈,Google开发Android的人也是典型的理想主义!

如果你只是简单地开启了一个后台线程来做数据下载(或者其他不是Service的办法),你将会得到你想要的结果:如果用户在你的UI里,系统将会确保你的进程运行,所以下载绝不会被中断。当用户离开了你的UI,你的进程仍将被保持(缓存)因而可以继续下载数据,只要RAM不告急就行。

同样,为了将你的APP的不同部分连接起来,你也没有理由去绑定同一个进程中的Service。这样做倒是没有什么明显的害处,因为系统会看到,该进程对自己有一个依赖,它将会忽略这个依赖,仍将你的APP当作普通进程看待。但是这样做对你和系统实际上都是没有必要的。作为替代,你可以使用单例或者其他进程内的模式来将你的APP的各部分连接到一起。

ContentProvider


最后,ContentProvider是一个专用的办法,用来将你的APP的数据公开到其他地方。人们通常会将它们当作对数据库的抽象,因为有许多的API和支持库就是这样使用ContentProvider的。但是从系统设计的角度,这并不是ContentProvider的初衷。

对于系统来说,ContentProvider实际上是一个入口,用于获取一个APP内部的公开的被命名的数据项(data items),每个数据项都被一个URI scheme所标识。这样,APP就可以决定怎样将自己的数据项映射到一个URI scheme,怎样将这个URI scheme公开给其他APP或者系统,好让APP或者系统使用这个URI scheme来获取自己内部的数据。这将让系统能够用一些很独特的方式来管理你的APP:

  1. 将URI scheme公开出去并不要求你的APP一直保持运行,所以即使你的APP没有运行,这些URI scheme也可以公开给任何APP和系统。只有当某个人告诉系统:“请把这个URI代表的数据拿给我。”时,系统将会让你的APP运行起来向你索要对应于URI的数据项并返回给请求者。

  2. 这些URIs也提供了一个很重要的细粒度的安全模型。比如,你的APP可以将代表一张你的APP内的图片的URI放在剪贴板上,但是让它的ContendProvider 保持在锁定状态,所以没有人能够自由地获取它。当其他APP从剪贴板上获取了这个URI,并向系统请求获取对应的图片时,系统可以给它一个临时的“URI许可”,以便让它仅能获取该URI所对应的图片,你的APP的其他内容都是安全的。
    自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

尾声

如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

架构篇

《Jetpack全家桶打造全新Google标准架构模式》

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

《Jetpack全家桶打造全新Google标准架构模式》**
[外链图片转存中…(img-wY6BXG1m-1713749884840)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 17
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值