ServiceTracker 的作用

如果您的服务消费者需要了解某一接口下的服务对象何时注册、何时取消注册,这时,您应使用 ServiceTracker 类:

 

下面,我们看看如何使用服务跟踪器来修改我们的示例代码,具体步骤如下。

1) 修改HelloWorldBundle的MANIFEST.MF文件,让它导入org.osgi.util.tracker包;

2) 新建类HelloServiceTracker.java,其源代码参见清单11。

源代码清单11.HelloServiceTracker.java

Java代码   收藏代码
  1. public   class  HelloServiceTracker  extends  ServiceTracker {    
  2.    
  3.     public  HelloServiceTracker(BundleContext context) {    
  4.    
  5.         super (context, HelloService. class .getName(), null );    
  6.    
  7.     }    
  8.    
  9.     public  Object addingService(ServiceReference reference) {    
  10.    
  11.         System.out.println("Inside HelloServiceTracker.addingService "  + reference.getBundle());    
  12.    
  13.         return   super .addingService(reference);    
  14.    
  15.     }    
  16.    
  17.     public   void  removedService(ServiceReference reference, Object service) {    
  18.    
  19.         System.out.println("Inside HelloServiceTracker.removedService "  + reference.getBundle());    
  20.    
  21.         super .removedService(reference, service);    
  22.    
  23.     }    
  24.    
  25. }    

 

在上面的HelloSerivceTracker类的构造函数中,您可以看到,我们把HelloService接口名传入其父类中,这相当于说,HelloServiceTracker应跟踪注册到HelloService接口名下的所有服务,HelloServiceTracker继承自ServiceTracker 类,实现了下面两个方法:

a) addingService()方法:当Bundle使用 接口名注册服务时,该方法将会被调用;

b)removedService()方法:当Bundle取消注册某个接口名下的服务时,该方法将会被调用。

3) 用HelloServiceTracker类更新我们的Activator.java类,以便让它来管理服务,而不是直接去查找它们,源代码请参见清单12。

源代码清单12. 使用 了HelloServiceTracker的Activator.java

Java代码   收藏代码
  1. public   class  Activator  implements  BundleActivator {    
  2.    
  3.     HelloServiceTracker helloServiceTracker;    
  4.    
  5.     public   void  start(BundleContext context)  throws  Exception {    
  6.    
  7.         System.out.println("Hello World!!" );    
  8.    
  9.         helloServiceTracker= new  HelloServiceTracker(context);    
  10.    
  11.         helloServiceTracker.open();    
  12.    
  13.         HelloService helloService = (HelloService)helloServiceTracker.getService();    
  14.    
  15.         System.out.println(helloService.sayHello());    
  16.    
  17.      
  18.    
  19.     }    
  20.    
  21.     public   void  stop(BundleContext context)  throws  Exception {    
  22.    
  23.         System.out.println("Goodbye World!!" );    
  24.    
  25.         helloServiceTracker.close();    
  26.    
  27.     }    
  28.    
  29. }   

 

我们看到,在初始的start()方法中,我们首先新建一个HelloServiceTracker对象,然后要求这个对象跟踪HelloService接口下的服务。这时,我们可以调用getService()方法获得HelloService对象。

如果您试运行上面的示例代码,您会注意到,在启动或停止HelloSerivceBundle时,OSGi 容器都会调用HelloServiceTracker对象的addingService()方法或removedService()方法。

 

总结: 由此可见ServiceTracker与context.getService(reference)的最大区别是,ServcieTracker封装了ServiceListener可以在Service发生变化时被触发,比较适合热插拔。

你可能感兴趣的:(osgi,ServiceTracker)