Q1:Service的两种启动方式:
1.startService
2.bindService(有回调可以和activity进行通信)
注意:在Android 5.0之后google出于安全的角度禁止了隐式声明Intent来启动Service,也禁止使用Intent filter,否则就会抛出异常
Q2:启动与停止Service两种方式
第一种:通过startService()与stopService()启动和停止服务,Service与启动它的Activity无法进行通信和数据交换
第二种:通过bindService()与unbindService()启动和停止服务。在启动时,通过bindService(Intent, ServiceConnection, int)启动服务,unbindService(ServiceConnection) 停止服务,ServiceConnection参数为交互数据的对象
Q3:Activity和Service的交互方式主要有以下几种?
- 通过广播进行交互
- bindService()启动service,进行交互
- 通过共享文件
- Messenger
- AIDL
Q4:onStartCommand的几种返回值有什么效果?
在service的onStartCommand()方法中有个返回值,返回值一般分为下面三种,表示当service异常销毁的时候,service后续启动情况。
- START_NOT_STICKY: service如果被干掉,不会再自动重启。
- START_STICKY:service如果被干掉,会自动重启,但是onStartCommand回调方法的Intent参数为null。如果你的Service可以在任意时刻运行或结束都没什么问题,而且不需要intent信息,那么就可以在onStartCommand方法中返回START_STICKY,比如一个用来播放背景音乐功能的Service就适合返回该值。
- START_REDELIVER_INTENT:service如果被干掉,会自动重启,Android系统会再次将Service在被杀掉之前最后一次传入onStartCommand方法中的Intent再次保留下来并再次传入到重新创建后的Service的onStartCommand方法中,这样我们就能读取到intent参数。如果我们的Service需要依赖具体的Intent才能运行(需要从Intent中读取相关数据信息等),并且在强制销毁后有必要重新创建运行,那么这样的Service就适合返回START_REDELIVER_INTENT。
Q5:service保活有哪些方法?
- onStartCommand方法返回START_STICKY或者START_REDELIVER_INTENT;
- 提高Service的优先级,在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。
- 在Service即将销毁的时候重新启动;或者注册一个广播,然后在service的onDestroy中发送广播,在广播中实现拉起;
- 提升service进程优先级,使用前台服务;
- 通过系统的一些广播,比如:手机重启、界面唤醒、应用状态改变等等监听并捕获到,然后判断我们的Service是否还存活
- 开启一个守护进程,实时监听;
- AlarmManager + JobScheduler;
- 双进程守护,AIDL方式单进程、双进程方式保活Service;
- 白名单:跳转到系统白名单界面让用户自己添加app进入白名单;
- 安装到system/app,使其成为系统应用。
Q6:service生命周期
1、startService启动服务:
startService()执行的生命周期:onCreate() —> onStartCommand()
1)点击启动Service服务startService()
单次点击:onCreate() —> onStartCommand()
多次点击:onCreate() —> onStartCommand() —> onStartCommand()—> onStartCommand()... ...
注意:多次启动服务onCreate()只会执行一次,onStartCommand()会执行多次。
2)点击停止Service服务stopService()
onDestroy()
2、bindService绑定服务:
bindService执行的生命周期:onCreate() —> onBind()—> onUnbind() —> onDestroy()
1)点击绑定Service服务bindService()
onCreate() —> onBind()
2)点击解绑Service服务unbindService()
onUnbind() —> onDestroy()
bindService 如果被不断的重复调用,会有问题吗? - 旺仔牛轧糖 - 博客园
如果调用bindService()方法前服务已经被绑定,多次版调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的权服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
采用Context.bindService()方法启动服务,在服务百未被创建时,系统会先调用服务的onCreate()方法,度接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先问调用服务的onUnbind()方法,接着调用答onDestroy()方法。
3、先启动后绑定服务
先点击startService然后点击bindService的生命周期:
onCreate() —> onStartCommand()—> onBind()—> onUnbind()—> onDestroy()
1)点击启动,然后点击绑定Service服务:startService()—> bindService()
onCreate() —> onStartCommand() —> onBind()
2)先点击停止,然后点击解绑Service服务:stopService() —> unbindService()
onUnbind() —> onDestroy()
4、先绑定后启动服务
先bindService后startService的生命周期:
onCreate() —> onBind()—> onStartCommand()—> onUnbind()—> onDestroy()
1)启动绑定Service服务bindService()—> startService()
onCreate() —> onBind() —> onStartCommand()
2)先点击解绑,然后点击停止Service服务:unbindService() —> stopService()
onUnbind() —> onDestroy()
5、先解绑后绑定服务
先解绑后绑定Service服务unbindService() —> bindService()
onUnbind(ture) —> onRebind()
引申问题Q7:多次bindService但是被绑定service的onBind只走一次的解决办法
多次bindService但是被绑定service的onBind只走一次的解决办法_牛客博客
多组件绑定同一个service,出现问题:只有第一个服务绑定的时候会调用onBind()方法,并且service返回的都是同一个service:
原因:要指定多组件绑定service,输入的时候bindservice会认为intent是一样的,就会默认使用第一次调用的onbind传回的IBinder,这样的话,会发现服务绑定的内存地址也是同一个。其实就是它一直用的第一个服务绑定的地址。
解决办法:给intent指定一个type,区分多次intent的类型即可:
//main button点击事件 :绑定服务1
public void bindClick(View view){
Log.v("chendandan","bindClick()");
if(myConn==null){
myConn=new MyConn();
}
Intent intent=new Intent(MainActivity.this,MyService.class);
//指定type
intent.setType("main");
bindService(intent,myConn,BIND_AUTO_CREATE);
}
//child buttion点击事件:绑定服务2
public void bindClick(View view){
Log.v("chendandan","bindClick()");
if(myConn==null){
myConn=new MyConn();
}
Intent intent=new Intent(MainActivity2.this,MyService.class);
//指定type
intent.setType("child");
bindService(intent,myConn,BIND_AUTO_CREATE);
}
运行结果:
引申问题Q8:多次bindService但是被绑定service的onBind只走一次的原因
情况一: App A绑定App B的service,App A多次调用bindService(),而不调用unbindService(),此时App B的service的onBind()只执行一次
情况二: App A,App C绑定App B的service,App A和App C各调用一次或多次bindService(),而不调用unbindService(),此时App B的service的onBind()只执行一次
上面提到的两种情况有2个共同点:
(1)每次调用bindService()时,绑定的服务是一样的;
(2)没有调用unbindService()
Android中bindService的细节之三:多次调用bindService(),为什么onBind()只执行一次?_weixin_41205419的博客-CSDN博客_多次调用bindservice