Service : 服务
windows: 长期后台运行没有界面的进程就叫服务.
android: 长期后台运行,没有界面的组件, 服务是运行在当前应用程序进程里面
创建个类继承Service
在清单文件声明
<service android:name=".ServiceListener"></service>
重写方法:
IBinder onBind(Intent intent)
onCreate():打开
onDestroy():关闭
在MainActivity里面调用方法开启关闭服务
// 系统时钟.休眠
SystemClock.sleep(2000);
// 开启服务
startService(intent);
//关闭服务
stopService(intent);
Service的生命周期,从它被创建开始,到它被销毁为止,可以有两条不同的路径:
A started service
被开启的service通过其他组件调用 startService()被创建。
这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。
当service被停止时,系统会销毁它。
A bound service
被绑定的service是当其他组件(一个客户)调用bindService()来创建的。
客户可以通过一个IBinder接口和service进行通信。
客户可以通过 unbindService()方法来关闭这种连接。
一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service。
这两条路径并不是完全分开的。
即是说,你可以和一个已经调用了 startService()而被开启的service进行绑定。
比如,一个后台音乐service可能因调用 startService()方法而被开启了,稍后,可能用户想要控制播放器或者得到一些当前歌曲的信息,可以通过bindService()将一个activity和service绑定。这种情况下,stopService()或 stopSelf()实际上并不能停止这个service,除非所有的客户都解除绑定。
public class ExampleService extends Service
{
int mStartMode; // indicates how to behave if the service is killed
IBinder mBinder; // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used
// 创建 只被执行一次
@Override
public void onCreate()
{
// The service is being created
}
// 开始命令 由系统每次调用客户端通过调用显式启动服务
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// The service is starting, due to a call to startService()
return mStartMode;
}
// 绑定 返回到服务的通信通道
@Override
public IBinder onBind(Intent intent)
{
// A client is binding to the service with bindService()
return mBinder;
}
// 取消绑定
@Override
public boolean onUnbind(Intent intent)
{
// All clients have unbound with unbindService()
return mAllowRebind;
}
// 重新绑定
@Override
public void onRebind(Intent intent)
{
// A client is binding to the service with bindService(),
// after onUnbind() has already been called
}
// 销毁
@Override
public void onDestroy()
{
// The service is no longer used and is being destroyed
}
}
Activity透明化
<application
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<!-- android:theme="@android:style/Theme.Translucent.NoTitleBar"透明界面,相当于隔着一层玻璃 -->
</application>
Binder:服务内部中间人
private class MyService extends Binder 继承Binder代理人
如果不想对外暴露隐私方法,只允许实现公共的,就定义一个接口对外暴露去实现。
onBind(Intent intent){return null//null改为继承代理人的类} :服务成功绑定的时候,返回服务中的代理人
bindService(Intent service, ServiceConnection conn,int flags){}绑定服务调用的方法
//int flags 填充 BIND_AUTO_CREATE如果服务不存在,会把服务创建出来.
ServiceConnection:界面监视应用程序服务的状态。看到android.app.Service , Context.bindService()的更多信息。像许多从系统回调,这个类的方法调用你的主线程的过程。
// 作为中间人传递获取数据
private class MyConn implements ServiceConnection{
//当服务被成功连接的时候调用的方法.onServiceConnected(ComponentName name, IBinder service)
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("在Activity得到了服务返回的代理人对象,IBinder");
myBinder = (IService) service;
}
//当服务失去连接的时候调用的方法.onServiceDisconnected(ComponentName name)
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
// IService.Stub绑定数据进行,进程间通讯
// .Stub: 局部面IPC实现存根类。
// IPC> inter process communication 进程间通讯
public class MyConn extends IService.Stub {
@Override
public int basicTypes(String account, String password, int money) throws RemoteException {
return safePay(account, password, money);
}
}
绑定方式开启服务的生命周期
绑定的方式开启服务,如果服务不存在, oncreate—>onbind
服务的onstart和onstartcommand方法不会被执行.
解除绑定服务 onunbind()—>ondetroy()
多次绑定服务,服务只会被创建一次,oncreate方法只会被执行一次
多次绑定服务,onbind方法不会被重复调用.
在实际开发的时候,如果需要调用服务的方法,就绑定服务,只能绑定一次
服务只可以被解绑一次,如果用同一个conn对象多次解绑,服务会抛出一次.
请严格按照步骤编写代码:
- start的方式开启服务 (保证服务长期后台运行)
- bind的方式绑定服务 (调用服务的方法)
- unbind的方式解除绑定服务
- stop的方式停止服务
.aidl 跨进程使用
android interface definition language 安卓接口定义语言
自己定义的接口后缀名,更改成.aidl,代码里面不用添加 public private ,则会在gen文件自动生成.java文件
在Android Studio里面创建.aidl文件
New —> AIDL 文件
我们可以在目录 build–>generated–>source–>aidl–>test–>debug下面发现还没有任何文件,此时我们同步下刷新即可生成的.aidl文件可以使用 IService.Stub.asInterface(android.os.IBinder obj);来绑定文件
java.lang.SecurityException: Binder invocation to an incorrect interface 异常
原因及解决方法:
在上请注意,服务端与客户端都要有相同的接口(使用到的),这里的“相同”是指完全相同,包括包名,也就是说要在不同工程下建立相同的包名,这样一来,问题应该迎刃而解了!