基础
如何绑定service?
- 创建一个bound service
- 在组件中调用bindService()方法进行绑定
如何创建一个bound Service呢?
继承Service,用于绑定的类,首先,必须提供一个IBinder用于与客户端(例如Activity)
交互,有三种方式可以提供此IBinder,每一种方式又有不同的实现方式。
- 继承Binder(实现了IBinder)类
- 使用Messenger
- 使用AIDL
其次是在onBind()中返回IBinder
**Notice:**多个clients连接到service时,只在第一次绑定时调用onBind()方法获取
IBinder对象,对于其他的clients,系统直接传递一个IBinder,不会再调
用onBind()方法.
创建bound service三种方式可以提供此IBinder,如何选择呢?
- 继承Binder: 在servie只能在本应用中使用,并且不涉及多进程时使用(也就是与 客户端处于相同的进程中)
- 使用Messenger:当想要IBinder工作于不同的进程中,并且不在意请求的同时执行,使用 此方法.这是最简单方式对于IPC,因为Messenger队列请求都是单线程的 无需考虑线程安全问题。
- 使用AIDL:首先,使用Messenger是基于AIDL,当想要同时处理多个请求时可以使用此方式,当 要自己处理多线程和线程安全问题。
**Notice:**不是所有组件都能绑定service,广播就是个例外,但广播可以启动service。
bound service
继承Binder如何定义bound service,组件中如何使用?
- service定义
1.1 在Service中Binder的对象,此对象中包含组件可以使用的共有方法,在公有方法中返回service对象,或者返回有service托管的类(类中要有public方法)。
1.2:在onBind()方法中返回Binder对象。 - 组件中绑定service
2.1组件中onServiceConnected()方法中获取IBinder并操作。
/******继承Binder方式bound service定义的模板******/
public class LocalService extends Service {
//返回到给客户端(例如Activity)
private final IBinder mBinder = new LocalBinder();
/*
* 继承Binder
*/
public class LocalBinder extends Binder {
LocalService getService() {
//返回service对象客户端能调用service的public方法。
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/*客户端(例如activity)中能够调用此方法*/
public int getTest {
return 12;
}
}
public class BindingActivity extends Activity {
//保存获取service的对象
LocalService mService;
//用于标志是否service绑定了
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// 绑定service
Intent intent = new Intent(this, LocalService.class);
//第二个参数Serviceonnection对象
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// 解除绑定
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
//button
public void onButtonClick(View v) {
if (mBound) {
int num = service.getTest();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
/*由于bindService是立即的返回,没有值返回,而ServiceConnection用于监听
*连接的当建立连接了就会调用onServiceConnected(),从而可以获取到IBinder
*/
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
使用Messenger如何定义bound service,组件中如何使用?
- 在Service中定义一个Handler用于处理来自client的请求,
- 使用Handler对象作为参数来创建一个Messenger对象
- 在onBind()方法中使用Messenger对象返回一个IBinder对象,
- 在clients中的ServiceConnection的onServiceConnetion()中根据IBinder 对象来实例化Messenger,
public class MessengerService extends Service {
static final int MSG_SAY_HELLO = 1;
/**
* 1. 定义一个Handler用于处理来自client的请求
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!",
Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* 2. 使用Handler对象作为参数来创建一个Messenger对象
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* 3. 在onBind()方法中使用Messenger对象返回一个IBinder对象,
*/
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
public class ActivityMessenger extends Activity {
Messenger mService = null;
/**用于判断是否已连接*/
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
//4 根据IBinder对象来实例化Messenger,
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected
mService = null;
mBound = false;
}
};
//Button
public void sayHello(View v) {
if (!mBound) return;
Message msg = Message.obtain(null,
MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class),
mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
**Notice:**这里没有演示service对client的回应,一个很好的例子时APIDemo中MessengerService.java和MesengerServiceActivity的例子。
上面对于clients绑定service很模糊,究竟怎么连接?
- 实现ServiceConnection
1.1 onServiceConnected() client-service建立连接就会调用此函数, 传递onBind()中创建的IBinder。
1.2 onServiceDisconnected() client-service之间的连接断开时会调用这个函数。 - 调用bindService时传递一个ServiceConnection实现。
- 当解除绑定时调用unbindService方法。
Intent intent = new Intent(this, LocalService.class);
//BIND_AUTO_CREATE:如果Service没有在运行,就自动创建。
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Skill: * Activity与service交互是在Activity可视时应该bindService() 在onCreate(),unbindService()在onStop()中 ,Activity在后台也能接受service的回应,那可以在onCreate()中调用bindService,在onDestory()中调用unbindService().
Notice: 不应该绑定在onResume(),在onPause()解除定,在多个Activity来回切换的话可能导致service不断的销毁,然后在重建,
service生命周期
started service
bound service
开启服务与绑定了服务共存
**Notice:**在开启service和绑定service都存在时,
- 先解除所有绑定,会调用onUnbind(),但不会调用onDestroy()方法,当调用stopService()或者stopSelf()时才会调用onDestroy(),
- 先调用stopService()或者stopSelf()时,由于service没有解除绑定, 此时不会调用onDestroy(),当所有绑定都解除,才会调用onDestroy()。
- 也就说只要servie使用中,就不会调用onDestroy().