Android知识点一

1.service

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

区别:
startService只是启动Service,启动它的组件(如Activity)和Service并没有关联,只有当Service调用stopSelf或者其他组件调用stopService服务才会终止。

bindService方法启动Service,其他组件可以通过回调获取Service的代理对象和Service交互,而这两方也进行了绑定,当启动方销毁时,Service也会自动进行unBind操作,当发现所有绑定都进行了unBind时才会销毁Service。

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

答:Service的onCreate是在主线程(ActivityThread)中调用的,耗时操作会阻塞U

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

答:线程和Handler方式

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

答:

2.Broadcast

Normal broadcasts无序广播,会异步的发送给所有的Receiver,接收到广播的顺序是不确定的,有可能是同时。

Ordered broadcasts有序广播,广播会先发送给优先级高(android:priority)的Receiver,而且这个Receiver有权决定是继续发送到下一个Receiver或者是直接终止广播。

问:除了上面的两种广播外,还有其他类型的广播吗?

答:可以使用sendStickyBroadcast发送Sticky类型的广播。Sticky简单说就是,在发送广播时Reciever还没有被注册,但它注册后还是可以收到在它之前发送的那条广播。

问:有时候基于数据安全考虑,我们想发送广播只有自己(本进程)能接收到,那么该如何去做呢?

答:可能使用Handler,没错,往主线程的消息池(Message Queue)发送消息,只有主线程的Handler可以分发处理它,广播发送的内容是一个Intent对象,我们可以直接用Message封装一下,留一个和sendBroadcast一样的接口。在handleMessage时把Intent对象传递给已注册的Receiver。

后来在看项目组的其他同事写代码时,发现还有一个LocalBroadcastManager类,查了一下官方文档是Support V4包里的一个类,其实现方式也是使用Handler,思路也是一样的。

问:BroadcastReceiver的生命周期

答:有些人并不态清楚Receiver也是有生命周期的,而且很短,当它的onReceive方法执行完成后,它的生命周期就结束了。这时BroadcastReceiver已经不处于active状态,被系统杀掉的概率极高,也就是说如果你在onReceive去开线程进行异步操作或者打开Dialog都有可能在没达到你要的结果时进程就被系统杀掉。因为这个进程可能只有这个Receiver这个组件在运行,当Receiver也执行完后就是一个empty进程,是最容易被系统杀掉的,所以一般不要操作耗时任务。替代的方案是用Notificaiton或者Service(这种情况当然不能用bindService)。

问:使用广播来更新界面是否合适?

答:更新界面也分很多种情况,如果不是频繁地刷新,使用广播来做也是可以的。但对于较频繁地刷新动作,建议还是不要使用这种方式。广播的发送和接收是有一定的代价的,它的传输是通过Binder进程间通信机制来实现的(细心人会发现Intent是实现了Parcelable接口的),那么系统定会为了广播能顺利传递做一些进程间通信的准备。

除此之外,还可能有其他的因素让广播发送和到达是不准时的(或者说接收是会延时)。曾经看到有人在论坛上抱怨发几个广播都卡,Google的工程师是怎么混饭吃的。

这种情况可能吗?很可能,而且很容易发生。我们要先了解Android的ActivityManagerService有一个专门的消息队列来接收发送出来的广播,sendBroadcast执行完后就立即返回,但这时发送来的广播只是被放入到队列,并不一定马上被处理。当处理到当前广播时,又会把这个广播分发给注册的广播接收分发器ReceiverDispatcher,ReceiverDispatcher最后又把广播交给接Receiver所在的线程的消息队列去处理(就是你熟悉的UI线程的Message Queue)。

整个过程从发送--ActivityManagerService--ReceiverDispatcher进行了两次Binder进程间通信,最后还要交到UI的消息队列,如果基中有一个消息的处理阻塞了UI,当然也会延迟你的onReceive的执行。

3.Activity

问:如果一个Activity在用户可见时才处理某个广播,不可见时注销掉,那么应该在哪两个生命周期的回调方法去注册和注销BroadcastReceiver呢?

答:Activity 的可见生命周期发生在 onStart调用与 onStop调用之间。在这段时间,用户可以在屏幕上看到 Activity 并与其交互。我们可以在 onStart中注册一个 BroadcastReceiver以监控影响 UI 的变化,并在用户无法再看到您显示的内容时在 onStop中将其取消注册。

如果对方回答是在onResume和onPause方法中,那么你可以去引导对方看看在这两个方法有什么不好的地方。

问:如果有一些数据在Activity跳转时(或者离开时)要保存到数据库,那么你认为是在onPause好还是在onStop执行这个操作好呢?

答:这题的要点和上一题是一样的,onPause较容易被触发,所以我们在做BroadcastReceiver注销时放在onStop要好些。onPause时Activity界面仍然是可见的,如弹出一个Dialog时。但在保存数据时,放在onPause去做可以保证数据存储的有效性,如果放在onStop去做,在某些情况下Activity走完onPause后有可能还没顺利走到onStop就被系统回收了。

但要注意在onPause中要非常迅速地执行完所需操作,不然会影响到下一个Activity的生命周期函数的调用。

问:简单说一下Activity A启动Activity B时,两个Activity生命周期的变化。

答:当一个 Activity 启动另一个 Activity 时,它们都会发生生命周期转变。第一个 Activity 暂停然后停止(但如果它在后台仍然可见,则不会停止,比如B是半透明的),系统会创建另一个 Activity。 如果这两个Activity 共用保存数据到文件或者数据库,必须要注意,在创建第二个 Activity 前,第一个 Activity 不会完全停止。更确切地说,启动第二个 Activity 的过程与停止第一个 Activity 的过程存在重叠。

以下是当 Activity A 启动 Activity B 时一系列操作的发生顺序:
Activity A 的 onPause方法执行。
Activity B 的 onCreate、onStart和 onResume方法依次执行。
然后,如果 Activity A 在屏幕上不再可见,则其 onStop方法执行。

您可以利用这种可预测的生命周期回调顺序管理从一个 Activity 到另一个 Activity 的信息转变。 例如,如果您必须在第一个 Activity 停止时向数据库写入数据,以便下一个 Activity 能够读取该数据,则应在 onPause而不是 onStop执行期间向数据库写入数据。

你可能感兴趣的:(Android知识点一)