service是Android四大组件之一,与activity最大的区别就是:它没有界面,像一个无脸男一样。
写一个service需要继承Service类,有一个必须override的方法:onBind,它返回一个Binder对象
(虽然onBind方法的声明是:public IBinder onBind(Intent itnt),但IBinder是以I打头的,它是一个接口,而Binder类是它的实现类)
最简单的方式是继承Binder类用于传输数据(当然后面还有更复杂一些的Messenger和AIDL)
利用继承Binder类的方式实现一个Server,这个Server是无法用于多个进程间通信(即IPC)的,它只能够被调用
(使用Messenger通常用于IPC但不适用于处理大量并发请求,而AIDL用于IPC且适用于大量并发请求)
启动一个Service有两种办法,即startService和bindService,两种启动方式的生命周期也是不同的
具体的可以看一下:service生命周期
而且两种方式还有一个很重要的区别,用startService开启一个Service,它不能与Service之间进行通信,而用bindService开启(绑定)的话将可以与Service进行通信。
先写一个MyService(继承Service):
public class MyService extends Service{
MyBinder myBinder = new MyBinder();
int sec;
boolean quit = true;
public class MyBinder extends Binder{
public int getSecond() {
return sec;
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
quit = false;
new Thread() {
public void run() {
while(!quit) {
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
}
sec++;
}
};
}.start();
}
@Override
public IBinder onBind(Intent itnt) {
// TODO Auto-generated method stub
return myBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
this.quit = true;
}
}
它在内部开启了一个线程用于计数,当然,为了让线程自然死亡,设置了一个quit标识来控制线程何时消亡。
定义完一个Service类后,可以在AndroidManifest.xml文件中添加如下代码,(方便其他进程调用)
<service android:name=".MyService">
<intent-filter >
<action android:name="com.arial.action.SERVICE"></action>
</intent-filter>
</service>
这里我只添加了action属性
接下来在MainActivity里实现Service的调用:
第一步:新建刚刚在MyService里写的MyBinder类(用于与Service之间进行通信)并新建内部类ServerConnection
MyService.MyBinder binder;
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
tv.setText("服务终止了");
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
// TODO Auto-generated method stub
binder = (MyService.MyBinder)arg1;
}
};
第二步:在某一时刻(可以是按键触发,也可以是onResume、onCreate等方法里)绑定服务
final Intent intent = new Intent();
intent.setAction("com.arial.action.SERVICE");
bindService(intent, conn, BIND_AUTO_CREATE);
或者直接写成
bindService(new Intent().setAction("com.arial.action.SERVICE"), conn, BIND_AUTO_CREATE);
最后一个参数指的是绑定方式,BIND_AUTO_CREATE指的是绑定后自动启动
这样你就已经在使用这个Service了。最后一步一定要记得把Service关掉(若是用bindService启动的Service,在Activity调用unBind后它也会消亡)。
你可以使用onServiceConnected的第二个参数与你定义的MyBinder里的方法与Service进行通信,如下:
int sec = binder.getMinute();
第三步:在某一时刻(可以是按键触发或者onStop、onDestroy中)调用unBind解绑Service
unbindService(conn);
该方法传入的参数就是ServiceConnection。