Android菜鸟的成长笔记(18)——绑定本地Service并与之通信

来源:互联网 发布:淘宝卖耐克 编辑:程序博客网 时间:2024/05/21 17:39

在上一篇中介绍了Service与Activity的区别及Service两种启动方式中的第一种启动方式startService().

我们会发现用startService()、stopService()方法启动和关闭一个Service时,Service与访问者之间基本上不存在太多的关联,因此Service和访问者之间也无法进行通信和数据交换。如果要实现Service与Activity之间的通信就要使用第二种启动方式(绑定启动)bindService()启动、unbindService()关闭。

下面我们来看一下bindService方法的各个参数的含义:(下图是API中关于该方法的说明)

官方说明地址:http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)

各个参数的大致含义如下:

service:通过Intent指定要启动的Service.

conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service对象的onServiceConnected(ComponentName name, IBinder service)方法:当Service所在的宿主进程由于异常终止或者由其他原因终止,导致该Service与访问者之间断开连接时回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。

  1. private ServiceConnection conn = new ServiceConnection() {  
  2.       
  3.     @Override  
  4.     public void onServiceDisconnected(ComponentName name) {  
  5.         System.out.println("--Service Disconnected--");  
  6.     }  
  7.       
  8.     @Override  
  9.     public void onServiceConnected(ComponentName name, IBinder service) {  
  10.         System.out.println("--Service Connected--");  
  11.         binder = (MyBinder) service;  
  12.     }  
  13. };  

flags:指定绑定时是否自动创建Service.该参数为0则不自动创建,为BIND_AUTO_CREATE(自动创建)

注意:当调用者主动通过nubindService()方法断开与Service的连接时,ServiceConnection对象的onServiceDisconnected(ComponentName name)方法不会被调用。

可以看到上面onServiceConnected方法中有一个IBinder的参数对象,实际上Activity与Service之间的绑定是通过该参数进行绑定和通信的。这时候可能有的朋友就有点迷糊了,这到底是怎样实现通信的呢?

其实,当你在开发一个Service的时候Service类会强制你实现一个方法onBind(Intent intent).在绑定本地(没有跨越进程)Service的情况下,onBind(Intent intent)方法返回的IBinder对象将会传给上面介绍的bindService()方法参数ServiceConnection对象的o中的IBinder.这样访问者就可以通过操作该参数中IBinder对象来实现对Service中数据的读取。

在实际开发中通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

下面我们来实现一个绑定的Service与Activity之间的通信:

(1)建立一个service返回Binder对象

  1. package com.example.testservice;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.Binder;  
  6. import android.os.IBinder;  
  7.   
  8. public class BindService extends Service{  
  9.       
  10.     private int count;  
  11.     private boolean quit;  
  12.     //定义onBinder方法所返回的对象  
  13.     private MyBinder binder = new MyBinder();  
  14.     //通过继承Binder来实现IBinder类  
  15.     public class MyBinder extends Binder{  
  16.         public int getCount(){  
  17.             return count;  
  18.         }  
  19.     }  
  20.       
  21.     @Override  
  22.     public IBinder onBind(Intent intent) {  
  23.         System.out.println("Service is Binded");  
  24.         return binder;  
  25.     }  
  26.       
  27.     @Override  
  28.     public void onCreate() {  
  29.           
  30.         super.onCreate();  
  31.         System.out.println("Service is Created");  
  32.         new Thread(){  
  33.             public void run() {  
  34.                 while(!quit){  
  35.                     try {  
  36.                         Thread.sleep(1000);  
  37.                     } catch (InterruptedException e) {  
  38.                         // TODO Auto-generated catch block  
  39.                         e.printStackTrace();  
  40.                     }  
  41.                     count++;  
  42.                 }  
  43.             };  
  44.         }.start();  
  45.     }  
  46.       
  47.     @Override  
  48.     public boolean onUnbind(Intent intent) {  
  49.         System.out.println("Service is UnBinded");  
  50.         return super.onUnbind(intent);  
  51.     }  
  52.       
  53.     @Override  
  54.     public void onDestroy() {  
  55.         super.onDestroy();  
  56.         this.quit = true;  
  57.         System.out.println("Service is Destroyed");  
  58.     }  
  59.       
  60.   
  61. }  
(2)创建ServiceConnection接口实例对象,并将该对象的实例作为参数传给bindService()方法,通过调用ServiceConnection接口实例中的nServiceConnected方法的参数获得IBinder对象。
  1. package com.example.testservice;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Service;  
  5. import android.content.ComponentName;  
  6. import android.content.Intent;  
  7. import android.content.ServiceConnection;  
  8. import android.os.IBinder;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.Button;  
  12. import android.widget.Toast;  
  13.   
  14. import com.example.testservice.BindService.MyBinder;  
  15.   
  16. public class BindServiceTest extends Activity{  
  17.     Button bind, unbind, getServiceStatus;  
  18.       
  19.     BindService.MyBinder binder;  
  20.       
  21.     private ServiceConnection conn = new ServiceConnection() {  
  22.           
  23.         @Override  
  24.         public void onServiceDisconnected(ComponentName name) {  
  25.             System.out.println("--Service Disconnected--");  
  26.         }  
  27.           
  28.         @Override  
  29.         public void onServiceConnected(ComponentName name, IBinder service) {  
  30.             System.out.println("--Service Connected--");  
  31.             binder = (MyBinder) service;  
  32.         }  
  33.     };  
  34.       
  35.     protected void onCreate(android.os.Bundle savedInstanceState) {  
  36.         super.onCreate(savedInstanceState);  
  37.         setContentView(R.layout.main);  
  38.           
  39.         bind = (Button)findViewById(R.id.button1);  
  40.         unbind = (Button) findViewById(R.id.button2);  
  41.         getServiceStatus = (Button) findViewById(R.id.button3);  
  42.           
  43.         final Intent intent = new Intent();  
  44.           
  45.         intent.setAction("com.meritit.service.BIND_SERVICE");  
  46.           
  47.         bind.setOnClickListener(new OnClickListener() {  
  48.               
  49.             @Override  
  50.             public void onClick(View arg0) {  
  51.                 bindService(intent, conn, Service.BIND_AUTO_CREATE);  
  52.             }  
  53.         });  
  54.           
  55.         unbind.setOnClickListener(new OnClickListener() {  
  56.               
  57.             @Override  
  58.             public void onClick(View v) {  
  59.                 unbindService(conn);  
  60.             }  
  61.         });  
  62.           
  63.         getServiceStatus.setOnClickListener(new OnClickListener() {  
  64.               
  65.             @Override  
  66.             public void onClick(View v) {  
  67.                 Toast.makeText(BindServiceTest.this"Service的count值是:" + binder.getCount(),  
  68.                         Toast.LENGTH_SHORT).show();  
  69.             }  
  70.         });  
  71.     };  
  72. }  
通过该方法Activity可以非常方便的访问到Service的运行状态,这里的IBinder可以看成Service组件所返回的代理对象。
0 0
原创粉丝点击