(一)生命周期相关的类
BundleActivator接口是作为OSGI framework的一个入口,一般来说每个bundle需要定义自己Activator类,并实现这个接口.
当bundle start的时候会调用BundleAcivator的start方法,对应的bundle stop的时候调用BundleActivator的stop方法.
在start()方法中进行一些程序初始化的工作,例如获得需要的resource,初始化类, stop()方法需要释放resource.
我们可以把start()方法理解为java程序的public static void main(String[]),也就是程序的入口.
public interface BundleActivator {
public void start(BundleContext context) throws Exception;
public void stop(BundleContext context) throws Exception;
}
BundleContext是bundle生命周期的上下文,对于某个bundle在它的生命周期中,它的BundleConext是唯一的而且不会发生变化的.
public interface BundleContext {
...
String getProperty(String key);
Bundle getBundle();
Bundle installBundle(String location, InputStream input) throws BundleException;
Bundle installBundle(String location) throws BundleException;
Bundle getBundle(long id);
Bundle[] getBundles();
void addBundleListener(BundleListener listener);
void removeBundleListener(BundleListener listener);
void addFrameworkListener(FrameworkListener listener);
void removeFrameworkListener(FrameworkListener listener);
...
}
对于每一个installed的bundle,在内存中都会有一个Bundle类的实例跟它对应,也就是 Bundle实例就是bundle在内存的表示.
每个bundle在内存中是唯一的,用一个唯一的bundleId来表示,而不是用metadata中的SynbolicName+version来表示.
另外需要说明的是OSGI framework都有一个系统的bundle,这个系统的bundleId=0
public interface Bundle {
...
BundleContext getBundleContext();
long getBundleId();
Dictionary getHeaders();
Dictionary getHeaders(String locale);
String getLocation();
int getState();
String getSymbolicName();
Version getVersion();
void start(int options) throws BundleException;
void start() throws BundleException;
void stop(int options) throws BundleException;
void stop() throws BundleException;
void update(InputStream input) throws BundleException;
void update() throws BundleException;
void uninstall() throws BundleException;
...
}
(二)生命周期状态图
当BundleContext调用installBundle()的时候,bundle成为intalled的状态.bundle处于这个状态还不一定可以使用,因为bundle中可以依赖其他的bundle,这些依赖的bundle是否被加载还没有确定.
这个状态的变迁一般是隐含的,当activator.start()的正式执行执行,或者依赖这个bundle 的其他bundle加载这个bundle的类的时候,还可以通过程序来使bundle处于这个状态.
starting状态时临时的,当activator.start()的时候,一般来说也是隐含的.如果 start()方法调用成功,则到下一个状态acitve,如果抛出异常,则返回到resolved状态.
active表示bundle正在运行,随时可以被停止.
当activator.stop()的时候,停止以后回到resolved状态.
当bundle没有被install或者已经installed的被uninstall以后的状态.
(三)状态相关的API
Bundle bundle = this_BundleContext.installBundle(url );
如果这个url对应的bundle已经installed了,那么就直接返回对应的bundle.
要启动bundle,首先要得到bundle,得到bundle的api为
Bundle bundle = this_BundleContext.getBundle(bundle_id );
然后
bundle.start();
就是这么简单. 如果没有异常抛出,则bundle的状态会从installed->starting->resolved->active.(假设开始状态为installed)
如果有异常,因为dependency bundles的原因,则回到原来的状态.
已经处于active的调用这个方法不做任何事情.
如果bundle处于starting/stopping状态,则需要等待状态的下一步变化再做处理.
同start一样,要停止bundle, 首先要得到它.
然后
bundle.stop();
如果调用stop之前的状态是active,则成功调用stop()后,状态时resolved.
bundle不能stop自己.
先得到bundle,然后bundle.update()或bundle.update(ur l)
更新bundle 的jar包.如果bundle处于active状态,framework会先stop.
先得到 bundle,然后
bundle.uninstall()
(四)其他API
//得到 BundleContext中所有的bundle:
Bundle[] bundles = m_context.getBundles();
//得到bundle的状态
bundle.getState()
//得到bundle的头(metadata)信息
bundle.getHeaders();
//得到bundle名称 (其他属性类似)
(String)bundle.getHeaders().get(Constants.BUNDLE_NAME);
//得到bundle的url
bundle.getLocation()
//得到bundle的唯一标识
bundle.getSymbolicName());
//访问bundle私有的文件
File file = the_BundleContext.getDataFile("log.txt");
(五)事件机制
osgi framework提供了两种事件:BundleEvent 和 FrameworkEvent. 前者是bundle相关的事件,后者是Framework相关的事件.
有了事件必然有相对应的listener : BundleListener 和 FrameworkListener. 还有addListener和removeListener,这里就不说了.
public interface BundleListener extends EventListener {
public void bundleChanged(BundleEvent event);
}
public interface FrameworkListener extends EventListener {
public void frameworkEvent(FrameworkEvent event);
}
每种event都有type,具体看api文档吧.
(六) PackageAdmin
PackageAdmin接口提供了
public boolean resolveBundles(Bundle[] bundles);
可以单独做resolve这一步,而不是隐含的.
public void refreshPackages(Bundle[] bundles);
当update或者uninstall之后,可能会造成 bundle不一致,这时候需要刷新.
刷新的过称中,active的bundle需要变成resolved状态.