在处理将OSGi嵌入到应用程序/库中,在运行时加载bundle然后在宿主应用程序/库中使用该bundle时,我有点迷失。
这是从我的主机加载捆绑包的代码:
// 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()方法?
答案 0 :(得分:2)
简而言之:
更详细的解决方案:
或者,如果您没有应用程序/库中的接口,您仍然可以获得OSGi服务并使用反射调用该函数。
答案 1 :(得分:2)
以下是有关在上一个答案后使用的代码的一些详细信息:
包含您的方法的界面。
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();
}
}
}
包含激活器和实现的bundle需要在其文件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的动态。这项服务可能在两次通话之间进行!
希望它可以帮到你, 亨利