上篇中我们演示了如何通过Event方式来实现Bundle间的通信。Bundle中类的缺省访问范围只对本Bundle内部可见,但对其它任何Bundle都是不可见的;在Bundle内部,类的可访问性遵循Java语言的一般规范。那么,如果想要从一个Bundle中访问另一个Bundle中的类,该怎么办呢?解决方法是将源Bundle中的包导出来,然后把它们导入到目标Bundle中,就能实现Bundle之间类的访问了。下面以一个实际例子来说明:
1:首先我们建立一个bundle A 工程(工程名为my.osgi.bundle.access.a),然后工程中进行如下操作
A:新建一个ClassAccess类,代码如下:
package my.osgi.bundle.access.a;
public class ClassAccess {
public void saySomething() {
System.out.println("Inside ClassAccess.saySomething() of bundle A ");
}
}
B:将该Package导出
在manifest 文件中添加下列红色标注部分
Manifest-Version: 1.0
Bundle-Vendor: 456
Bundle-Version: 1.0.0
Bundle-Name: my.osgi.bundle.access.a
Bundle-ManifestVersion: 2
Bundle-Activator: my.osgi.bundle.access.a.Activator
Bundle-Description: 123
Import-Package: org.osgi.framework
Bundle-SymbolicName: my.osgi.bundle.access.a
Export-Package: my.osgi.bundle.access.a
2:接下来我们建立一个bundle B工程(工程名为my.osgi.bundle.access.b),然后工程中进行如下操作
A:将上文中Bundle A 导出的Package导入
在manifest 文件中添加红色标注部分
Manifest-Version: 1.0
Bundle-Vendor: 456
Bundle-Version: 1.0.0
Bundle-Name: my.osgi.bundle.access.b
Bundle-ManifestVersion: 2
Bundle-Activator: my.osgi.bundle.access.b.Activator
Bundle-Description: 123
Import-Package: org.osgi.framework,my.osgi.bundle.access.a
Bundle-SymbolicName: my.osgi.bundle.access.b
B:Activator类中start方法中添加如下两行代码
ClassAccess newClassAccess = new ClassAccess();
newClassAccess.saySomething();
详细代码如下:
/*
* Created on Fri Aug 10 17:17:09 CST 2012
*/
package my.osgi.bundle.access.b;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import my.osgi.bundle.access.a.ClassAccess;
public class Activator implements BundleActivator {
/* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
ClassAccess newClassAccess = new ClassAccess(); //添加
newClassAccess.saySomething(); //添加
}
/* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
}
工程截图如下:
3:编译工程,分别会生成my.osgi.bundle.access.a-1.0.0.jar和 my.osgi.bundle.access.b-1.0.0.jar两个Bundle。
4: knopflerfish运行,加入以上两个Bundle, 先运行my.osgi.bundle.access.a-1.0.0.jar,然后运行my.osgi.bundle.access.b-1.0.0.jar
输出结果如下:
[stdout] Waiting the calling from bundle B
[stdout] Inside ClassAccess.saySomething() of bundle A
由此可见,通过导入导出Package 的方式,Bundle A 已经能访问Bundle B 中的类 。