android 浏览器源码分析,从源码出发深入理解 Android Service

原标题:从源码出发深入理解 Android Service

原文链接:

建议在浏览器上打开,删除了大量代码细节,:)

本文是 Android 系统学习系列文章中的第三章节的内容,介绍了 Android Service 相关的基础知识,然后从源码的角度上分析 Service 的一些实现原理。对此系列感兴趣的同学,可以收藏这个链接 ,也可以点击 进行订阅

0X00 Service 基础知识

Service 作为 Android 提供的四大组件之一,主要负责一些没有前台显示的后台任务。即使应用本身不再可见,Service 的属性也能使得其在后台运行。除此之外,Service 也可以通过 Binder 机制,与界面甚至其他应用进行进程间通信,以实现相应的交互。这里需要简单说明的是,既然是后台任务,为什么不选用 Thread 了?选用 Service 和 Thread 的主要区别在于需不需要在应用不可见的时候依然保留。举例来说,新闻详情页面的数据请求,只用在当前页面生效,而音乐播放这些后台任务就可以通过 Service 的方式来实现。

关于如何使用 Service,官方教程已经说明得足够详细了,如果对这些用法,还有不清晰的地方,请戳这里进行查看,-> 。官方教程里面包括,startService 和 bindService 的区别,在不同场景下应该选用哪种 Service 实现方式。

0b2a789f549e77d9afac681300984082.png

0X01 startService 调用流程

从前面的教程里面,可以知道 Service 的启动一般有两种方式,分别是 bindService 和 startService。这里主要说明 startService, 具体的实现逻辑在 ContextImpl 中,我们看看源码是怎么实现的。

接下来,看看方法内部具体是怎么实现的。

从上面的代码可以看到,这里是通过 ActivityManagerNative 来执行的。如果看过我的另一篇文章,, 可能会觉得很熟悉。事实上这里采用的机制就是同样的。

ActivityManagerNative 的 getDefault 方法是这么实现的。可以看到,gDefault 是类型为 IActivityManager 的 Binder 对象。而这个 Binder 对象可以看做是在 System Server 中的 ActivityManagerService 的句柄,通过这个 Binder 对象,可以跨进程调用 ActivityManagerService。

如果上述内容不容易理解的话,我们可以类比地来看这个问题。我们遥控电视的时候,例如进行增加音量的操作,这个操作实际不是由遥控器完成的,而是电视中的电子元件完成的。遥控器会和电视进行协商,先声明有哪些操作可以执行,然后将这些协商后的操作在遥控器端和电视端 �� 都实现,区别在于电视机是真的实现,而遥控器只是发送操作指令而已。前面代码中提及的 gDefault 就是 ActivityManagerService 的遥控器。

接着往下看看电视端是具体怎么操作的,这里的电视端就是 ActivityManagerService.

看起来具体的逻辑,都在类型为 ActiveServices 的 mServices 对象中。ActiveServices 是 AMS 专门用来管理 Service 的类,大部分和 Services 相关的逻辑都在这里面。

可以看到 startServiceLocked 主要进行了权限校验和为性能进行的调度,具体的逻辑,还在 startServiceInnerLocked 方法里面。

接下来看看 bringUpServiceLocked 是如何实现的,这里就是实际启动 Service 的地方。

上面的代码较为复杂,这里进行下初步的总结。首先判断服务是否已经启动,或者正在重启中,则直接返回。其后,当前 Service 进程正在启动中,也直接返回。最后判断应用进程是否启动,如果没有启动进程,则先启动进程。

上面代码的重点在于 app.thread, 这个 IApplicationThread 对象同样也是一个 Bindle 接口,与前文提交的 gDefault 不同之处在于两者的方向是相反的。前者是应用进程操作AMS,而后者则是AMS操作应用进程。IApplicationThread 对应的实现是 ApplicationThread,我们看看这个类是如何处理 scheduleCreateService 这个方法的。

原来还是通过 mH Handler 这种方式来执行的呀,这与前面文章提及的知识是完全一样的。如果大家想详细地了解的话,建议看看这些系列文章 。在 Handler 中的 handleMessage 是如何处理 CREATE_SERVICE 这个消息的?

继续看 handleCreateService 方法的实现。

方法实现相对简单,首先通过 ClassLoader 加载相关的 class 对象,然后将 Service 和 Application 绑定在一起,最后调用 Service 的 onCreate 方法。到此为止,Service 就完全启动了。

如果使用 Service 的方式是 startService,那么在 Service 启动后,就可以执行 sendServiceArgsLocked 方法,从而在 Service 的 onStartCommand 里面可以执行相应的后台代码,需要特别说明的是,这个是执行在 UI 线程上的,因而建议不要执行耗时的任务,如果是耗时的任务,需要通过多线程的方式来避免主线程的阻塞。即使应用当前不在前台,阻塞 UI 线程,也是很不好的情况。

我们看看 sendServiceArgsLocked 是如何实现的。

这里通过循环的方式,将在队列中的消息,依次通过 app.thread 发布到应用进程中去,如果中途发生了 TransactionTooLargeException 异常,则会提前终止这个过程。app.thread 的 scheduleServiceArgs 方法,也是通过 mH 这个 Handler 来执行的,发送的消息为 SERVICE_ARGS。

handleServiceArgs 方法中,s.onStartCommand 就是我们书写后台代码的地方,当这个方法执行完成后,又通过 gDefault 这个遥控器通知 AMS 来任务完成了。

对于 startService 这种方式而言,是需要手动调用 stopSelf 方法来结束 Service 的,背后的原理与 startService 方法类似,这里就不再赘述。

0X01 bindService 调用流程

bindService 相较于 startService 要复杂一些,通过这种方式实现的 Service,容易多个组件绑定到它,通过 ServiceConnection 的方式来进行通信。当没有任何其他组件,连接到这个 Service 时,该 Service 会自动销毁。

bindService 方法是这样声明的。

可以看到同样是通过 gDefault 这个遥控器来通知 AMS 进行相应的操作的,原理与上面 startService 相同,接收到遥控器的指令后,ActiveServices 的 bindSericeLocked 方法开始执行。bindSericeLocked 在进行一些校验,确认进程创建成功等等步骤后,还是通过 app.thread 发送 BIND_SERVICE 消息,来执行对应的逻辑。

在 onBind 方法,给调用者返回 Binder 对象,通过 publishService 方法通过到 AMS 内部去,我们看看接下来发生了什么。

ActiveServices 中的代码也相对简单, 遍历建立起的 ServiceConnection,并调用它们的 connected 方法,这也是我们需要编写后台代码的地方。

0X02 总结

Service 作为四大组件之一,提供了不需要前台页面情况下,在后台继续执行任务的能力。Service 一般有两种使用方式,分别是通过 startService 和 bindService,前者适合执行一次性的任务,而后者则具备一定交互的能力,可以用作处理相对复杂的后台逻辑。

关于更多详细的用法,还是建议阅读官方教程,.

文档信息

版权声明:自由转载-非商用-非衍生-保持署名()

发表日期:2016年9月20日

社交媒体:

Feed订阅:

一周好

责任编辑:

自从Android火起来以后,各大互联网及科技产品相继推出自己的客户端,争夺这块庞大的市场。而作为互联网入口的浏览器更是成为第一突破口,放眼望去,现如今各大浏览器都发布了自己的Android客户端,然而个人觉得手机浏览器市场一如桌面浏览器一样,鱼龙混杂,参差不齐,利益关联,广告泛滥。缺乏人性化的用户体验和不够单纯的功能设置,让人望而却步。   除了QQ浏览器,UC,遨游……,我相信大家肯定还是更倾心于现如今手机浏览器的老大海豚浏览器,其次就是紧随其后的Opera。海豚浏览器作为手机浏览器的龙头长期高居Android Market的排行榜首,不得不承认海豚浏览器现在已经比较成熟,各项功能都非常贴心,有人将其比喻为手机浏览器中的“火狐”,我想并不为过。但是现在,追求个性的你有了另一个不错的选择,这就是今天要推荐的Android浏览器Zirco-browser。   相对于海豚浏览器来说,Zirco是一个比较小众的浏览器,用户量可能微乎其微,但是经过使用测试,个人认为这是一个值得推荐的浏览器。   Zirco是一款开源的浏览器,默认显示中文界面。最新9月28日更新版本0.4.1,软件大小456k。根据反复测试,显示效果不输给任何浏览器,页面加载速度超越海豚浏览器!   Zirco浏览器特性: 无限制的选项卡浏览,左右循环滑动切换; 支持书签导入导出; 搜索引擎定制; 插件支持; User Agent; 同步Firefox 书签; 自由缩放; 地址栏搜索; 主页自定义; Ad-blocker; 页面内查找; 更多……    效果图:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值