一、service
一个服务是 不是 一个单独的进程。
一个服务是 不是 一个线程。
service的两种模式(startService()/bindService()不是完全分离的)
· 它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
· 它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。
当一个服务组件被创建时,有可能是以上两种原因,系统实际上做的是实例化该组件并调用它 的onCreate() 和任何其他适当的回调主线上。 它是由服务来实现这些行为与适当的操作,如创建一个辅助线程在它执行其。
二、Service生命周期
Service与Activity一样,也有一个从启动到销毁的过程。Service的生命周期过程只有3个阶段:
1、创建服务
2、开始服务
3、销毁服务
一个服务实际上是一个继承android.app.Service的类。
onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStart(Intent intent,int startId) 该方法在服务开始时调用,onStart方法会被调用多次
onDestroy()该方法在服务被终止时调用,整个生命周期中植被调用一次。
· 服务的完整生命周期始于调用onCreate()而终于onDestroy()方法返回。如同activity一样,服务在onCreate()里面进行它自己的初始化,而在onDestroy()里面释放所有资源。比如说,一个音乐回放服务可以在onCreate()中创建播放音乐的线程, 而在onDestroy()中停止这个线程。
· 服务的活跃生命周期始于调用onStart()。这个方法用于处理传递给startService()的Intent对象。音乐服务会打开Intent来探明将要播放哪首音乐,并开始播放。
服务停止时没有相应的回调方法──不存在onStop()方法。
onCreate()和onDestroy()方法在所有服务中都会被调用,不论它们是由Context.startService()还是由Context.bindService()所启动的。
如果一个服务允许别的进程绑定,则它还会有以下额外的回调方法以供实现:
IBinder onBind(Intent intent)
boolean onUnbind(Intent intent)
void onRebind(Intent intent)
传递给bindService的Intent的对象也会传递给onBind()回调方法,而传递给unbindService()的Intent对象同样传递给onUnbind()。如果服务允许绑定,onBind()将返回一个供客户端与服务进行交互的通讯渠道。如果有新的客户端连接至服务,则onUnbind()方法可以要求调用onRebind() 。
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。
使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。
如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。
采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。
采用Context.bindService()方法启动服务时只能调用onUnbind()方法解除调用者与服务解除,服务结束时会调用onDestroy()方法。
当然一个正在运行的服务也有可能被销毁onDestroy():这是发生在系统内存不足时
注意:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:<service android:name=".SMSService" />
一个简单的服务类:
view sourceprint?01 public class LocalService extends Service {
02
03 @Override
04 public void onCreate() {
05 Log.i("LocalService", "onCreate()");
06 super.onCreate();
07 }
08
09 @Override
10 public void onStart(Intent intent,int startId) {
11 Log.i("LocalService", "Received start id " + startId + ": " + intent);
12
13 super.onStrart();
14 }
15
16 @Override
17 public void onDestroy() {
18 Log.i("LocalService", "onDestroy()");
19 super.onDestory();
20 }
21
22 @Override
23 public IBinder onBind(Intent intent) {
24 return null;
25 }
26 }
在我们的客户端启动上面的服务:startService()启动
view sourceprint?01 public class StartAService extends Activity {
02 @Override
03 public void onCreate(Bundle savedInstanceState) {
04 ......
05 Button button =(Button) this.findViewById(R.id.button);
06 button.setOnClickListener(new View.OnClickListener(){
07 public void onClick(View v) {
08 Intent intent = new Intent(StartAService.this, SMSService.class);
09 startService(intent);
10 }});
11 }
12 }
BindService()启动继承的Service类实现onBind()方法
view sourceprint?1 public class LocalService extends Service {
2 private NotificationManager mNM; //通知管理对象
view sourceprint?01 public class LocalBinder extends Binder {
02 LocalService getService() { //获取被连接的服务对象
03 return LocalService.this;
04 }
05 }
06
07 @Override
08 public void onCreate() {
09 super.onCreate();
10 mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
11
12 // Display a notification about us starting. We put an icon in the status bar.
13 showNotification();//当创建一个服务时执行一个通知
14 }
15
16 @Override
17 public int onStartCommand(Intent intent, int flags, int startId) {
18
19 Log.i("LocalService", "Received start id " + startId + ": " + intent);
20 // We want this service to continue running until it is explicitly
21 // stopped, so return sticky.
22 return START_STICKY;
23 }
24
25 @Override
26 public void onDestroy() {
27 // Cancel the persistent notification.
28 mNM.cancel(R.string.local_service_started); //关闭通知
29
30 // Tell the user we stopped.
31 Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
32 super.onDestroy();
33 }
34
35 @Override
36 public IBinder onBind(Intent intent) {
37 return mBinder;
38 }
39
40 // This is the object that receives interactions from clients. See
41 // RemoteService for a more complete example.
42 private final IBinder mBinder = new LocalBinder();
43
44 /**
45 * Show a notification while this service is running.
46 */
47 private void showNotification() {
48 // In this sample, we'll use the same text for the ticker and the expanded notification
49 CharSequence text = getText(R.string.local_service_started);
50
51 // Set the icon, scrolling text and timestamp
52 Notification notification = new Notification(R.drawable.stat_sample, text,
53 System.currentTimeMillis());
54
55 // The PendingIntent to launch our activity if the user selects this notification
56 PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
57 new Intent(this, LocalServiceController.class), 0);
58
59 // Set the info for the views that show in the notification panel.
60 notification.setLatestEventInfo(this, getText(R.string.local_service_label),
61 text, contentIntent);
62
63 // Send the notification.
64 // We use a layout id because it is a unique number. We use it later to cancel.
65 mNM.notify(R.string.local_service_started, notification); //
66 }
67 }
view sourceprint?1 public class BindAService extends Activity {
2 private boolean mIsBound;
view sourceprint?1 private LocalService boundService;
view sourceprint?1 ServiceConnection conn = new ServiceConnection() {
2 public void onServiceConnected(ComponentName name, IBinder service) //参数二是一个IBinder类型的变量,
view sourceprint?1 {
view sourceprint?1 //将该参数转换成MyService.MyBinder对象,并使用MyBinder类中的getService方法获得MyService对象。在获得MyService对象后,
view sourceprint?1 //就可以在Activity中随意操作MyService了
2
3 //在这可以与连接的服务交互
view sourceprint?1
view sourceprint?1
view sourceprint?1 <BR>
view sourceprint?1 boundService= ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo.
view sourceprint?1 Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show();
2 }
3 public void onServiceDisconnected(ComponentName name) {
4 //连接服务意外中断处
view sourceprint?1 bundService= null;
view sourceprint?1 Toast.makeText(LocalServiceBinding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show();
2 }
3 };
4 @Override public void onCreate(Bundle savedInstanceState) {
view sourceprint?1 ......................
view sourceprint?1
view sourceprint?1 Button button1 = (Button)findViewById(R.id.unbind);
view sourceprint?1 button1.setOnClickListener(mUnbindListener);
2 Button button =(Button) this.findViewById(R.id.button);
3 button.setOnClickListener(new View.OnClickListener(){
4 public void onClick(View v) {
5 Intent intent = new Intent(BindAService.this, SMSService.class);
6 bindService(intent, conn, Context.BIND_AUTO_CREATE); //把服务绑定
7 //unbindService(conn);//解除绑定
8 }});
view sourceprint?1 private OnClickListener mUnbindListener = new OnClickListener() {
view sourceprint?1 public void onClick(View v) {
view sourceprint?1 if (mIsBound) { // Detach our existing connection.
view sourceprint?1 unbindService(mConnection);
view sourceprint?1 mIsBound = false; //销毁
view sourceprint?1 }
view sourceprint?1 }
view sourceprint?1 };
2 }
3 }