#服务
##01 start开启服务的生命周期(重点)
-
生命周期方法:oncreate() -->onstartCommand()--->onstartCommand()--->onDestory()
1.onCreate:在服务对象创建后调用这个方法,初始化服务对象 2.onStartCommand:开启服务后调用这个方法 3.onDestroy:在服务对象被销毁之前调用这个方法,通常在这个方法中做一些扫尾工作,比如保存数据
-
特点:
1.第一次开启服务时,先创建服务对象,然后再开启 调用的方法:onCreate,onStartCommand 2.停止服务调用方法:onDestroy() 3.服务可以被多次开启,每次开启时只调用onStartCommand方法 4.服务只能被停止一次,如果多次停止不会调用任何方法 5.没有界面,可以长期运行在后台(即使界面关闭掉了)
##02 bind开启服务的生命周期(重点)
-
生命周期方法: onCreate()-->onBind()-->onUnbind()-->onDestroy()
1.onCreate:在服务对象创建后调用这个方法,初始化服务对象 2.onBind()绑定服务 3.onUnbind()解除绑定的服务 4.onDestroy:在服务对象被销毁之前调用这个方法,通常在这个方法中做一些扫尾工作,比如保存数据
-
特点:
1.第一次绑定服务时,先创建服务对象,再绑定 调用的方法onCreate,onBind 2.解除绑定服务后服务就会停止 3.服务只能被绑定一次 4.服务只能被解除一次,多次解除会抛出异常
-
小细节:
1.如果onbind方法返回值是null,onServiceConnected方法就不会被调用 2.绑定的服务在系统设置界面,正在运行条目是看不到的 3.用的是什么conn绑定的,就必须用哪个conn去解绑 4.绑定的服务,不求同时生,但求同时死。 如果调用者Activity退出了,服务就自动跟着退出
##03 绑定服务调用服务里的方法
服务被绑定成功时,返回服务代理人;服务被连接成功时,拿到服务代理人
-
在Activity里绑定服务bindService()
bindService(intent, new MyConn(), BIND_AUTO_CREATE) intent: 意图对象,服务对应的意图对象 new Intnet(this,Service.class) ServiceConnection: 通讯频道,利用他可以获取到服务成功绑定后得到的代理人 BIND_AUTO_CREATE:常量,服务不存在会自动创建
-
如果服务被成功绑定,会执行 onBind的方法,让返回服务的代理人对象(IBinder类型) 返回值 IBinder 就是服务内部的小蜜
-
扩展实现服务内部的代理人,可以间接的调用服务的方法
public void callMethodInService(int money){ if(money>500){ methodInService(); }else{ Toast.makeText(DemoService.this, "这点钱还想办事呀?", 0).show(); } }
-
采用内部类的方式得到服务连接的通道
private class MyConn implements ServiceConnection{ //当服务被成功连接的时候调用的方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { 重要的参数IBinder ,代表的就是中间人,服务的小蜜 } //当服务失去连接的时候调用的方法 @Override public void onServiceDisconnected(ComponentName name) { } }
-
在MyConn成功连接后,就得到了 IBInder对象即MyBinder
-
利用MyBinder代理人间接调用服务的方法
##04 绑定服务抽取接口(重点)
接口: 可以隐藏代码内部的细节,只暴露程序员想暴露的方法
-
在工程中添加一个接口IService,在里面写一个方法callMethodInService()
-
让服务的代理人实现IService接口,实现接口的方法,在这个方法中调用服务的业务方法
-
服务被绑成功时,返回服务的代理人对象(IBinder类型)
-
服务连接成功时,拿到代理人IBinder,将其强转成IService类型
-
在activity中,通过调用代理人IService接口暴露出来的方法,间接调用服务里的业务方法
##05 混合方式开启服务,服务的生命周期
-
为什么需要采用混合的方式开启服务?
-
startService 服务长期后台运行,不可以调用服务里面的方法
-
bindService 可以调用服务的方法,但是不能长期后台运行
-
采用混合的方式开启服务: 即想服务长期在后台运行,又可以调服务里的方法
-
-
特点:
1. 如果服务被绑定了,只有解除绑定才能停止服务 2. 如果服务被采用start的方式开启过,只有stopService()才能停止服务
-
推荐使用的步骤:
1. startService(): 为了保证让服务长期运行在后台; 2. bindService(): 绑定服务,调用服务中业务方法; 3. unBindService(): 解除绑定,不再调用服务中业务方法; 4. stopService(): 停止服务
##06 服务的应用场景
应用场景:需要写一些代码运行在后台,执行一些任务.
##07 IPC进程间通信
- inter process communication 进程间通信
- aidl : android interface defination language安卓接口定义语言 满足两个进程之间接口数据的交换(ipc)
##08 本地服务和远程服务
-
本地服务: 服务的代码在自己应用程序工程的内部
-
远程服务: 同一个设备上的另一个软件中的服务组件
- 通过aidl接口暴露远程服务中的方法,任何应用程序都可以调用远程服务中的业务方法
##09 本地应用调用远程服务中方法 aidl的写法(重点)
通过aidl接口把远程服务中的业务方法暴露出去
-
创建一个远程服务的工程,写一个服务的组件,在服务中写一个业务方法
1. 在远程服务中把IService.java改成IService.aidl 把文件中public修饰符删除了 在工程目录gen目录下会自动编译成IService.java的接口文件。 2. 在远程服务中让代理人继承IService.Stub,Stub是远程服务的代理对象
-
创建本地应用,调用远程服务中方法:
3. 在本地应用中创建一个包,包名必须与远程服务中IService.aidl文件所在包名相同 4. 把远程服务中IService.aidl文件拷贝到本地应用的这个包下面 5. 在本地应用连接服务成功时,得到服务返回的代理人对象 mBinder = IService.Stub.asInterface(service) 6. 通过远程服务代理人对象间接调用远程服务中的业务方法
##10 远程服务的使用场景
- 超级大公司,写出来逻辑供别的程序员使用
- 手机企业,手机定制厂商,提供一些方便的逻辑供程序员使用。snoy手机,人脸识别
- 系统源码,内置很多的服务。电话服务TelephoneyManager LayoutInflaterService