转自:http://blog.csdn.net/andyhebear/archive/2008/07/23/2695698.aspx
RichClient Platform,顾名思义,是一个构建富客户端应用的平台,基于Eclipse的插件体系结构,由一系列所需要的最小插件集合所组成。一般来说,一个 RCP应用程序在发布时有两种类型:基于插件(Plug-in)和基于功能部件(Feature)的。为了使用 Eclipse平台所提供的丰富功能(比如Update,Web Start),我们必须开发基于功能部件的 RCP 应用。两者之间的转换也是非常容易的。这篇文章使用 Eclipse3.2版本作为开发平台,提供了一个小型的 RCP 应用例程,并使用 Update Manager 来实现产品的自动更新。
Eclipse RCP 是 Eclipse Platform 的一个子集(如图),从 Eclipse3.0版本开始,Eclipse项目组对代码进行了重构,将 IDE 与 Workbench(工作台)彻底分离,实现了一个 GenericWorkbench,使得基本的 RCP 应用中不再有 IDE 的影子。构成 RCP的最小插件集合包括Runtime,OSGi,SWT,JFace,Workbench 等一些必须的部件,还有一些是可选部件(比如 Help,Update 等,如下图所示),所有这些插件使得我们的 RCP 程序可以完成绝大部分的企业应用需求。
Update 是 RCP 的一个可选部件,它的主要功能包括:
1) 更新已经安装了的功能部件;
2) 寻找新的功能并进行安装;
3) 对已安装的功能部件进行配置。
这篇文章会围绕 Update 这个可选插件,使用 PDE 来开发一个具有自动更新功能的小型 RCP 应用程序。
建议读者先阅读下面的一些链接,以便对 RCP 有一个清晰的概念:
http://www.eclipse.org/articles/Article-RCP-1/tutorial1.html
http://www.eclipse.org/articles/Article-RCP-2/tutorial2.html
http://www.eclipse.org/articles/Article-RCP-3/tutorial3.html
![]() ![]() |
![]()
|
首先,我们需要一个插件,用来启动 RCP 应用,这个插件会包含基本的应用扩展点,请参考上面的链接。这里,我们使用 PDE 来创建一个 Eclipse 自带的具有一个视图(View)的例子程序。
启动 Eclipse,打开菜单File->New->Project, 选中Plug-in Project并且键入工程名,比如com.ibm.csdl.guardian.examples.。在下一页中,填写此插件的基本属性信息,对于问题 "Would you liketo create a rich client application?" 选择Yes. 最后,使用所提供的模板 "RCPapplication with a view" 并接受缺省设置来创建一个RCP的插件工程。
浏览插件配置文件plugin.xml, 我们会发现PDE创建了一个application的扩展,这个扩展将会作为RCP应用的程序入口,并且会被另外一个扩展:Product所使用(见本文产品部分)。
<extension id="application" point="org.eclipse.core.runtime.applications"> |
![]() ![]() |
![]()
|
为了使用应用程序的更新功能,我们必须为RCP定义一个或多个功能部件(Feature)。打开菜单File->New->Project, 选中 Feature Project 并且键入工程名称,比如com.ibm.csdl.guardian.examples.feature。在下一页,选中刚才所创建的插件工程: com.ibm.csdl.guardian.examples,作为此功能部件所包含的插件。
对于Eclipse3.2版本,一个可执行的RCP应用至少应包含下面的这些插件(Windows平台):
com.ibm.icu,
org.eclipse.core.commands,
org.eclipse.core.contenttype,
org.eclipse.core.expressions,
org.eclipse.core.jobs,
org.eclipse.core.runtime,
org.eclipse.equinox.common,
org.eclipse.equinox.preferences,
org.eclipse.equinox.registry,
org.eclipse.help,
org.eclipse.jface,
org.eclipse.osgi,
org.eclipse.swt,
org.eclipse.swt.win32.win32.x86,
org.eclipse.ui.forms,
org.eclipse.ui.workbench,
org.eclipse.ui.
并且,为了使用RCP应用程序的更新功能,还需要包含下面的几个插件:
org.eclipse.update.configurator,
org.eclipse.update.core,
org.eclipse.update.ui.
所以,同时选中这些插件来完成功能部件工程的创建。
最后,键入一个更新站点的URL和站点名称,Update Manager会使用这些信息来连接一个或多个更新站点。在这里,URL既可以使用网络地址,也可以使用本地的文件系统地址。下面是功能部件的配置文件feature.xml的典型内容:
… |
![]() ![]() |
![]()
|
RCP应用程序在启动时,需要一个application的扩展点或一个product的扩展点作为入口。同时,为了简化RCP应用程序的打包过程,我们使用一个产品配置文件来对例子程序进行设置。其中product 扩展点是基于application扩展点的。
在PDE 的Package Explorer视图中, 选中刚才所创建的RCP插件工程,打开菜单File->New->Product Configuration,键入一个产品配置文件名称,比如examples.product,并且使用缺省设置来完成产品配置的创建工作。
在产品配置编辑器(product configurationeditor)中,指定产品名称,比如examples。点击New按钮,使用缺省设置或指定一个产品标识,在RCP启动时会使用这个ID作为应用程序的入口。特别地,对于产品配置类型,要选择基于功能部件(features),否则无法使用更新功能。概览(Overview)页内容大致如下图所示:
切换到配置页,将我们的功能部件com.ibm.csdl.guardian.examples.feature 添加到部件列表中。如果必要,可以对其它页的属性信息进行更改,这里我们使用缺省值。最后,在插件配置文件plugin.xml中,添加product扩展:
<extension id="product" point="org.eclipse.core.runtime.products"> |
现在,我们可以切换到概览页,点击 "Launch the product" 来测试我们的RCP应用:
![]() ![]() |
![]()
|
这只是一个很简单的RCP应用,我们可以在此基础上添加透视图及视图以实现各种各样的功能,但这些不是本文的重点,请参考其它资料。这里,我们将在此应用的基础上添加软件更新功能。
首先,应该有一种方式,用来呼叫出更新管理器,我们使用菜单来实现这个功能。在类 ApplicationActionBarAdvisor中,修改 makeActions 方法,,添加一个Update Action:
… |
修改 fillMenuBar 方法,将Update菜单添加到Help主菜单下:
… MenuManager helpMenu = new MenuManager("&Help",IWorkbenchActionConstants.M_HELP); menuBar.add(helpMenu); helpMenu.add(updateAction); …
在类 UpdateAction 中,实现 run 方法如下:
BusyIndicator.showWhile(window.getShell().getDisplay(), new Runnable() { |
记得将 ore.eclipse.update.ui 这个插件添加到com.ibm.csdl.guardian.examples 插件的所需插件列表中,否则上面的类将不能通过编译。
好了,我们的RCP应用已经具备了软件更新功能!是不是感觉很简单?是的,Eclipse平台一个优美的地方就是将很多功能部件都设计成为一个 Framework,具有很高的可重用性,用户只需做很少量的工作就能实现很复杂的功能,Eclipse的UpdateManager就是一个很好的例子。再次启动我们的RCP应用,已经可以使用软件更新功能了,如下图。不过,因为更新站点并没有准备好,所以不会发现新的版本,下面会详细介绍这方面的内容。
到目前为止,这个例子程序一直是作为一个Eclipse的运行时应用来运行的,我们需要将其打包到Eclipse之外,形成一个单独的可执行的应用程序。得益于Eclipse的插件体系结构,打包的过程将非常简单。当然,我们可以自己编写脚本代码去完成这个步骤,但是在PDE中,提供了一个导出工具,使得我们可以更加方便的实现这个过程。首先确认插件工程下的build.properties文件包含了所有必需的资源文件,因为PDE的导出向导将会使用 Ant并读取这个配置文件来对每个插件进行打包工作。
现在使用产品配置编辑器打开 examples.product文件,切换到概览页,点击 "Eclipse Product exportwizard" ,弹出导出向导配置窗口。使用 examples.product作为配置文件并键入应用程序的主目录,比如ExampleRCP,PDE在打包时将会创建这个应用程序的根目录。另外,建议将"Synchronizebefore exporting"选中,以便在打包时检查配置文件是否与所包含的插件相匹配。最后,指定存放此RCP应用的目的文件夹并开始导出过程:
现在,我们可以进入刚才所指定的目的文件夹,通过双击可执行文件(在Launcher页进行配置)来启动应用程序。
假设一下产品已经发布出去,但是客户却想在树上显示四个节点,我们使用Update Manager来实现这个新的需求。
首先,需要在类View 中更改源代码:
… |
下一步需要创建一个更新站点的工程。打开菜单 File->New->Project,选择 Update Site Project,并且为此工程指定一个名称,比如com.ibm.csdl.guardian.examples.site.
在站点清单编辑器中,切换到Site Map页面,将不同的功能部件切分为类别。在Archives页面,设定更新站点的URL及描述信息,URL可以使用本地文件系统,或其它网络协议,比如HTTP等。为了方便测试,这里我们使用本地文件系统目录作为更新站点。
文件site.xml 最终的样子:
<site> |
在新版本编译通过之后,修改RCP应用包含的所有插件及功能部件的版本号,确保比发布给客户的版本要高(不要修改插件的ID),以表示有更新版本可用。
在插件com.ibm.csdl.guardian.examples 的MANIFEST.MF文件中:
… |
在feature.xml文件中:
<feature |
因为我们在功能部件的配置中使用了缺省设置 "Synchronize versions on build" ,所以PDE的打包工具会自动为所生成的二进制Jar文件生成正确的文件名以显示新的版本号。
现在的site.xml 文件内容:
<site> |
在站点清单编辑器的Site Map页面中,选中所要更新的功能部件并且点击 "Build",PDE会在此站点工程目录下生成所需要的更新功能部件及插件。将文件site.xml,目录features 和plugins拷贝到feature.xml中所指定的URL(在这里是本地文件系统), 再次启动我们的例子RCP应用,现在即可以使用"Find andInstall"菜单来对产品进行更新:
点击Next,会出现许可证描述信息(在feature.xml指定),只有选择接受许可证之后,下载更新包及安装过程才会继续:
下载并安装完毕之后,会提示重新启动RCP应用,这时即可以看到软件更新之后的效果:
为了使更新过程更加智能,UpdateManager还支持软件的自动更新,并提供了很多选项来对更新时间进行设置。我们所需要做的很简单,只需要将插件 org.eclipse.update.scheduler 添加到 feature.xml的插件包含列表中并添加一个菜单来呼叫出自动更新的配置项页面:
… |
从这里可以看出,Update Manager 使用org.eclipse.ui.preferencePages 这个扩展来对更新选项进行配置:
配置完成后,当更新条件满足时,RCP会自动弹出一个窗口,提示用户是否存在新的版本可用并进行安装。
有一点需要注意: 在更新到新的版本后(其实是下载新版本的插件Jar包),老版本的Jar 文件不会被自动删除,因为有时更新会出现问题,用户还可以再使用老的版本。对于这个问题,请参考下面这个链接来得到更多信息: https://bugs.eclipse.org/bugs/show_bug.cgi?id=70990.
一个大型的企业级RCP应用通常会包含大量的功能部件,如果有的功能部件暂时不会被使用,刚可以将其置为不可用状态,这样既可以加速应用程序的启动过程,也会对RCP应用的性能有所提高。Update Manager也提供了这个功能,我们的例子程序使用一个菜单来呼叫出管理窗口:
… |
在类 ManageAction 中,实现 run 方法如下:
BusyIndicator.showWhile(window.getShell().getDisplay(), new Runnable() { |
当点击此菜单后,即会弹出产品配置窗口,可以方便的管理所安装的功能部件:
![]() ![]() |
![]()
|
使用UpdateManager不仅可以方便的给RCP应用程序添加软件更新功能,还可以对所安装的功能部件进行方便的管理。得益于 UpdateManager的框架结构(其它Eclipse的组件也是如此),我们还可以利用其所提供的API,对产品的更新功能进行定制,使得产品具有自己的特色。