有的时候程序只需要在后台运行,而不需要和用户交互。比如说,QQ聊天工具,音乐播放器后台播放,QQ不在程序页面的时候同样可以收到好友发来的消息,音乐播放器离开程序页面的时候同样可以播放歌曲。下面就来聊聊Android四大组件之一的Service。Service的启动分两种:StartService、BinderService。对应的取消为:StopService、UnbinderService。
StartService、StopService
(退出当前Activity,Service依然运行)
首先创建一个HelloWorld的Android应用程序,创建一个名称为MyService的类,继承自Service。同时在MyService中重写方法onCreate()、onDestroy()。代码:
@Override
public IBinder onBind(Intent intent) {
// StartService的时候不调用
System.out.println("onBind");
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("onDestroy");
}
只是创建了类还是不行的,还要在配置文件AndroidManifest.xml文件中注册刚才的MyService类:
<service android:name = "MyService"></service>
并且在activity.xml文件中添加两个按钮,id分别为:btnStop,btnStop,标签为:启动、停止。同时在MainActivity中可以注册两个按钮,分别对应Service的两个方法onCreate()、onDestroy()。最后是在MainActivity中添加一个Intent对象.
private Intent serviceIntent;
private Button btnStart,btnStop;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serviceInent = new Intent(MainActivity.this,EchoService.class);
btnStart = (Button)findViewById(R.id.btnStart);
btnStop= (Button)findViewById(R.id.btnStop);
// 对按钮设置同一个监听器,MainActivity需要接口OnClickListener,重写onClick()
btnStart.setOnClickListener(this);
btnStop.setOnClickListerer(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startService(serviceInent);
break;
case R.id.btnStopService:
stopService(serviceInent);
break;
}
}
运行此程序,点击启动按钮,可以看到Logcat输出信息:onCreate,点击停止按钮,输出信息:onDestroy。
BinderService UnbinderService
(退出当前Activity,Service同样停止)
同样的,在activity_main.xml文件中添加两个按钮,ID分别为:btnBinderService,btnUnbinderService.标签分别为:BinderService,UnbinderService.并且在MainActivity中绑定和监听这两个按钮:
btnBindService = (Button) findViewById(R.id.btnBindService);
btnUnBindService = (Button) findViewById(R.id.btnUnbindService);
btnBindService.setOnClickListener(this);
btnUnBindService.setOnClickListener(this);
还有在onClick()方法中:
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startService(serviceInent);
break;
case R.id.btnStopService:
stopService(serviceInent);
break;
case R.id.btnBindService:
bindService(serviceInent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(this);
break;
}
}
在写bindService的时候,需要接口ServiceConnection,并且重写下面两个方法
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
System.out.println("onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 服务崩溃的时候调用
}
如果这个时候运行程序,点击BinderService按钮,Logcat的输出信息是没有onServiceConnected的,也就是说方法onServiceConnection没有被执行,问题出在哪里呢?在自己定义的MyService中,有一个onBind()方法,返回值为null,将返回值改为一个Binder类型的变量就可以了。
在MyService类中定义一个内部类:
public class MyServiceBinder extends Binder(){
}
并且实例化一个对象:
private final MyServiceBinder myServiceBinder = new MyServiceBinder();
最后只需要在onBind()方法中返回myServiceBinder就可以了。
运行程序:点击BindService按钮,Logcat:onCreate onbind onServiceConnection
点击UnbindService,Logcat:onDestroy
总结:假如先点击启动按钮的话,Logcat:onCreate
接着点击BindService,Logcat:onBind onServiceConnection,没有重新onCreate。也就是说,在操作系统中,一个Service只有一个实例。
假如一个Service即绑定了,又启动了,只是UnBindService的话,不会Destroy的,还需要StopService才回执行onDestroy方法的。