写点什么

已收藏!深入浅出 Android 性能调优

发布于: 13 小时前

这是我印象深刻的一道题,很明显它是我的第一次,那时我去一家公司(暂时叫它 T 公司吧)面试外派到韩国三星的工作机会。T 公司的面试官是一个叫 Bely 架构师,显然那个时候 Android 开发是稀缺资源,知道 Service 那都不得了了,当然 Bely 也没打算为难我(必竟也工作 4 年多了,人长得也不错),我轻松对答:


Service 是一个专门在后台处理长时间任务的 Android 组件,它没有 UI。它有两种启动方式,startService 和 bindService。


你猜得没错,Bely 紧接着问我:这两种启动方式的区别。


startService 只是启动 Service,启动它的组件(如 Activity)和 Service 并没有关联,只有当 Service 调用 stopSelf 或者其他组件调用 stopService 服务才会终止。bindService 方法启动 Service,其他组件可以通过回调获取 Service 的代理对象和 Service 交互,而这两方也进行了绑定,当启动方销毁时,Service 也会自动进行 unBind 操作,当发现所有绑定都进行了 unBind 时才会销毁 Service。


这应该是比较关键的区别了,在面试前我刚刚用 Serivce 做过一个音乐播放器。几年后,我在深圳面试过很多人,他们中有 60-70%的人没有使用 Service 的经验,让我一度感觉得深圳这座城市做 Android 开发的比较浮躁。因为这儿工作机会太多了,初级的开发者都比较急功近利,不需要在自己身上下太多的功夫也可以找到工作(当然这是片面的认识)。


当然还有其他的区别,如两种调用对 Service 生命周期函数影响,面试官也可以就这个问题展开一下。



当我遇到面试者知道怎么使用 Service,也如多年前的我可以自如的答出 startService 和 bindService 的区别时,我一般会多问一句:


Service 的 onCreate 回调函数可以做耗时的操作吗?


很多人都会说:可以。


原形毕露,他前面的回答只是在面试前预习了一下面试题而已。如果知道 Service 的 onCreate 是在主线程(ActivityThread)中调用的,耗时操作会阻塞 UI,我一般再接着问:


如果需要做耗时的操作,你会怎么做?


问题便这样展开了,一个人是否真正懂得原理会灵活运用,一下子便能看出来。 当面试者回答到线程和 Handler 方式时,我会再问一下对方:


是否知道 IntentService,在什么场景下使用 IntentService?


这也是面试官要看的点,真正的项目需要一个开发人员对某个问题有一定的深度,也需要对整个 Android 的知识点有一定的广度。深度代表这个人对问题认真对待有钻研的精神,广度代表这个人在面对同一个问题时,会更容易从多种可行的方案中选出最合适的一种。


Service 的实际项目中一直被很多人忽略,为什么我一再强调 Service 很重要,我们来看看,如果对 Service 完全无知会在工作中遇到什么问题。


场景:如果一个应用要从网络上下载 MP3 文件,并在 Activity 上展示进度条,这个 Activity 要求是可以转屏的。那么在转屏时 Actvitiy 会重启,如何保证下载的进度条能正确展示进度呢?


没有 Service 概念的人,一般想出来的方案如下:


  1. 在转屏前将进度缓存,转屏后再读出来。

  2. 使用 android:configChanges 设置,让转屏时 Activity 不销毁和重建。


针对第 1 个方案,我会继续问他将进度值存在哪里? 转屏的过程中,我们知道 Activity 的重建算是比较耗时的,会可能会有几百毫秒以上,那么这时候下载线程仍然在工作,进度肯定和保存时的进度不一致了,如何处理这个问题呢?


第 2 个方案,大家可以自己展开思考,实际的项目中可能会需要额外做一些事情来处理 ContentView 的横竖布局的问题。


如果使用 Service 来解决这个问题,看似是比较完美的,不过就会涉及 Activity(UI)和 Service 的交互问题,这个我们以后再讨论。



点击这里免费领取吧!

用户头像

VX公众号:编程进阶路 2020.11.28 加入

还未添加个人简介

评论

发布
暂无评论
已收藏!深入浅出Android性能调优