一.服务:实现程序后台运行的解决方案,并且可以和其他组件进行交互。
1.比如播放多媒体MP3,程序需要service在后台继续播放
2.比如检测SD卡上文件的变化
3.后台记录你地理信息位置的改变等等
总之服务是地下(后台)工作者。
二.服务的启动模式:
1.context.startService()
2.context.bindService()
三.两种服务生命周期:
(1)Context.startService的启动模式下的生命周期:当我们首次使用startService启动一个服务时,系统会实例化一个Service实例,依次调用其onCreate()和onStartCommand()方法,然后进入运行状态,此后,如果再使用startService启动服务时,不再创建新的服务对象,系统会自动找到刚才创建的Service实例,调用其onStart方法;这种service可以无限地运行下去,如果我们想要停掉一个服务,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。当service被停止时,系统会销毁它。此时onDestroy()方法会被调用,需要注意的是,不管前面使用了多个次startService(),只需一次stopService(),即可停掉服务。
(2)Context.bindService启动模式下的生命周期:在这种模式下,当调用者首次使用bindService绑定一个服务时,系统会实例化一个Service实例,并一次调用其onCreate()方法和onBind()方法,然后调用者就可以和服务进行交互了,此后,如果再次使用bindService绑定服务,系统不会创建新的Service实例,也不会再调用onBind方法;如果我们需要解除与这个服务的绑定,可使用unbindService()方法,此时onUnbind()方法和onDestroy()方法会被调用。
四.两种服务生命周期:
1.startService模式下调用者与服务无必然联系,即使调用者结束了自己的生命周期,只要没有使用stopService方法停止这个服务,通常情况下服务仍会运行;
2.bindService模式下服务是与调用者共生死的,在绑定完成之后,一旦调用者被销毁,服务也就立即终止,就像江湖上的一句话:You jump ,i'm jump! 翻译过来就是 你死了我也要随你一起死!
以前我们在使用startService启动服务时都是习惯重写onStart方法,在Android2.0时系统引进了onStartCommand方法取代onStart方法,为了兼容以前的程序,在onStartCommand()方法中其实调用了onStart方法,不过我们最好是重写onStartCommand方法。
public class MyService extends Service{
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i("Services", "onStart .");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.i("Services", "onBind.");
return null;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("Services", "nUnbind.");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("Services", "onDestroy called.");
}
}
四大组件在使用之前一定要记得注册,在AndroidManifest.xml中配置服务信息,不然这个服务就不会生效,配置如下:
1. <service android:name=".MyService">
2. <intent-filter>
3. <action android:name="android.intent.action.MyService" />
4. <category android:name="android.intent.category.DEFAULT" />
5. </intent-filter>
6. </service>
!!如果服务只是在本应用中使用的话 ,去掉<intent-filter>属性!!
1. /**
2. * 启动服务
3. * @param view
4. */
5. public void start(View view) {
6. new Intent(this, MyService.class);
7. startService(intent);
8. }
9.
10. /**
11. * 停止服务
12. * @param view
13. */
14. public void stop(View view) {
15. new Intent(this, MyService.class);
16. stopService(intent);
17.
18. }
以StartService模式启动服务生命周期如下:
10424 com.example.test222 Services onCreat. (不管点击几次启动服务,onCreat只执行了一次)
10424 com.example.test222 Services onStartCommand
10424 com.example.test222 Services onStart.
(二) 在看了startService()的启动模式后,再来看看bindService()
@Override
public void onClick(View v) {
if(v.getId()==R.id.button1){
//绑定服务的方法,需要的三个参数
Intent service;
ServiceConnection conn;
int flags;
bindService(service, conn, flags);
}else{
//解除绑定服务
unbindService(conn);
}
}
service: 通过该参数也就是Intent我们可以启动指定的service对象
ServiceConnection:代表与服务的连接,它只有两个方法,onServiceConnected()和onServiceDisconnected(),
onServiceConnected()是在操作者在连接一个服务成功时被调用,
onServiceDisconnected()是在服务崩溃或被杀死导致的连接中断时被调用,
而如果我们自己解除绑定时则不会被调用,所以我们这里只研究onServiceConnected这个方法。
flags:指定绑定时是否自动创建service
1. @Override
2. public IBinder onBind(Intent intent) {
3. "onBind called.");
4. return new Binder() {};
5. }
我们返回了一个Binder的实例,而这个Binder恰恰是实现了IBinder接口,所以这样就可以实现绑定服务的操作了
《》《》《》《》《》额外注意《》《》《》《》《》
当startService和bindService在同一场合下使用时,就会出现稍微不同的现象。
1.先调用startService然后点击bindService然后再点击stopService
如果我们先以startService方式启动服务,然后再用bindService绑定到这个服务,之后使用unbindService解除绑定,此时服务并不会因此而终止,而是会继续运行,直到我们使用stopService来停止这个服务。
2.先调用bindService然后点击startService然后再点击stopService
通过bindService启动服务的,之后只能靠unbindService来停止服务,并且只能调用一次,否则会挂掉,还有就是因为是绑定的,所以Activity退出的时候也会销毁这个服务