在将OSGi嵌入到应用程序/库中,在运行时加载捆绑软件然后在主机应用程序/库中使用该捆绑软件时,我有些迷惑。
这是从我的主机加载捆绑软件的代码:
// framework is the embedded OSGi framework
Bundle b = framework.getBundleContext().installBundle( "file:/project_dir/bundle/MyBundle.jar" );
b.start();
捆绑包包含一些非常简单的内容:
public class Activator implements BundleActivator
{
@Override
public void start( BundleContext context )
{
}
@Override
public void stop( BundleContext context )
{
}
public String shout()
{
return "let it all out";
}
}
如何从主机应用程序访问shout()方法?
最佳答案
以下是有关根据先前答案使用的代码的一些详细信息:
包含您的方法的接口。
public interface MyInterface {
String shout();
}
您会注意到,为库提供两个捆绑是一个好方法:一个捆绑用于接口,另一个捆绑用于实现。当实现包再次出现时,它将防止出现“刷新包”问题。
上一个接口的实现:
public class MyImpl implements MyInterface {
public String shout() {
return "let it all out";
}
}
该实现的包不需要通过捆绑包导出。服务使用者不会直接使用类
MyImpl
。激活器的新代码:
public class Activator implements BundleActivator {
private ServiceRegistration serviceRegistration;
@Override
public void start( BundleContext context ) {
this.serviceRegistration = context.registerService(
MyInterface.class,
new MyImpl(), new HashMap<String,String>());
}
@Override
public void stop( BundleContext context ) {
if (serviceRegistration!=null) {
serviceRegistration.unregister();
}
}
}
包含激活器和实现的捆绑软件需要将接口的包导入其文件
MANIFEST.MF
中。激活程序的软件包或实现都不需要在此文件中导出。它们必须保持在捆绑包内部。使用另一个捆绑软件中的服务的类
public void callService() {
ServiceReference<MyInterface> reference
= bundleContext.getServiceReference(MyInterface.class);
MyInterface foo = bundleContext.getService(reference);
try {
//use service
String msg = service.shout();
} finally {
bundleContext.ungetService( reference );
}
}
您会注意到,使用者仅需要导入接口的包(而不是实现的包)。此外,您需要小心处理OSGi的动态。该服务可能在两次通话之间就消失了!
希望对您有帮助,
蒂埃里