Android面试(二)

1. Service

Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念。Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的。

1.1 Service生命周期:

一. 被开启的Service通过其他组件调用startService()被创建。
这种Service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。当Service被停止时,系统会销毁它。当调用startService开启了Service,再调用startService,将不再执行onCreate,因为此时Service已经处于开启状态。
生命周期:onCreate() ---> onStartCommand() ---> onDestory()

二. 被绑定的Service通过其他组件调用bindService()被创建。
Activity可以通过一个IBinder接口和Service进行通信。Activity可以通过unbindService()方法来解除绑定。一个Service可以和多个Activity绑定,当多个Activity都被解除绑定之后,系统会销毁它。
生命周期:onCreate() -----> onBind() -----> onUnbind() ----> onDestory()

1.2 开启Service的两种方式以及区别:

startService:一旦通过这种方式开启Service,这个Service就会在后台一直运行,即使创建这个Service的Activity或Broadcast被销毁了,也会一直运行,除非手动地去关闭这个Service,这个Service才会停止。第一次调用startService方法时,onCreate方法、onStartCommand方法将依次被调用,而多次调用startService时,只有onStartCommand方法会被多次调用。可以调用stopSelf或者其它组件调用stopService来停止它,会走Service的onDestory。

bindService:通过这种方式开启的Service,会把Service和开启它的组件进行绑定,多次调用bindService,Service生命周期不会走,其它组件可以通过调用unbindService来解除绑定,会依次走onUnbind、onDestory。

1.3 Service和IntentService的区别:

Service:不是独立的线程,也不是独立的进程,而是依赖于应用程序的主线程的,也就是说,不建议在这里面直接执行耗时的逻辑和操作,为了解决这样的问题,Android给我们提供了IntentService。
IntentService:是继承Service的,故Service所有的生命周期,它都有,包含了Service的全部特性。与Service不同的是,IntentService执行onCreate()方法的时候内部开了一个线程HandlerThread,去执行耗时操作,HandlerThread在线程中发消息,接受处理完成后,然后进行onHandleIntent回调方法的执行,最后会清理线程,关闭服务。

1.4 Service中onStartCommond四种返回值策略:

一. START_STICKY:
如果Service进程被kill掉,保留service的状态为开始状态,但不保留传递的intent对象,随后系统会尝试重新创建service,调用onStartCommand(Intent, int, int)方法。
如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
强调一下,系统默认的就是START_STICKY。

二. START_NOT_STICKY:
“非粘性的”,使用这个返回值时,如果service进程被kill掉,系统不会自动重启该服务。

三. START_REDELIVER_INTENT:
重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

四. START_STICKY_COMPATIBILITY:
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

1.5Service和Thread的区别:

Thread是程序执行的最小单元,可以用来执行一些异步操作,处理耗时的任务。Service是依托于它所在的主线程的,而Thread是相对独立的。Service和Thread是没有任何关系的,之所以有人说有关系,还是因为Service翻译为服务,而服务被错误的理解成后台,就会被误认为是处理一些耗时的任务,然而其实Service是运行在主线程的,不能做耗时操作。而Thread是用来处理耗时逻辑的,他们两者并没有必然的联系。

为啥不在Activity中开启子线程,而是在Service中开启子线程?
因为在Activity中开启子线程,当Activity被销毁了,子线程是无法控制的,但是如果在Service中开启子线程,就无需担心这些,完全不用担心对子线程的控制,因为子线程都在Service中。

2Broadcast广播:

在Android中,Broadcast是一种广泛运用在应用程序之间传输信息的机制,Android中我们要发送的广播内容是一个Intent,这个Intent中可以携带我们要传送的数据。Broadcast可以实现不同程序间的数据传输与共享,只要和发送广播action相同的广播接收者,都可以接收到这个广播,也就是说,发送一个广播可以被很多广播接收者接收。

2.1 广播的使用场景:

同一app具有多个进程的不同组件之间的消息通信。
不同app之间的组件之间消息通信。

2. 2广播的种类:

普通广播:Context.sendBroadcast
有序广播:Context.sendOrderedBroadcast
本地广播:只在自身App内传播,由LocalBroadcastManager完成

2.3广播的实现方式:

静态注册:通过在AndroidManifest清单文件中用进行注册的,注册完成就一直运行,静态注册的广播即使Activity销毁了,甚至进程被杀死了,还是可以收到广播。
动态注册:跟随Activity的生命周期,是在代码中调用registerReceiver来进行注册的,会随着Actvity的销毁而销毁。

2.4 广播的实现机制:

自定义广播接收者BroadcastReceiver,并复写onReceive方法;
通过Binder机制向AMS(Activity Manager Service)进行注册;
广播发送者通过Binder机制向AMS发送广播;
AMS查找符合相应条件(IntentFilter / Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive方法。

2.5 LocalBroadcastManager详解:

使用它发送的广播将只在自身App内传播,因此你不必担心泄漏隐私数据
其它App无法对你的App发送该广播,因为你的App根本就不可能接收到非自身应用发送的该广播,因此你不必担心有安全漏洞可以利用
比系统的全局广播更加高效
LocalBroadcastManager高效的原因主要是因为它内部是通过Handler实现的,它的sendBroadcast方法含义并非和我们平时所用的一样,它的sendBroadcast方法其实是通过handler发送一个Message实现的。
既然它内部是通过Handler来实现广播的发送的,那么相比于系统广播通过Binder实现那肯定是更高效了,同时使用Handler来实现,别的应用无法向我们的应用发送该广播,而我们应用内发送的广播也不会离开我们的应用

你可能感兴趣的:(Android面试(二))