内容


使用 Eclipse 开发 eRCP 应用程序

利用 Eclipse V3.2 轻松实现富应用程序

Comments

背景知识

eRCP 是作为一种将 Eclipse Rich Client Platform(RCP)的优势应用到嵌入式设备之中的途径出现的。涉及的主题有:

  • 设置开发环境
  • eRCP 应用程序构造块
  • 如何为调试生成日志
  • 部署到实际设备上
  • RCP 和 eRCP 应用程序之间的主要差异

设置开发环境

在 Windows 开发机器上安装开发工具

最基本的 eRCP 开发环境包含以下组成部分:

  • Eclipse SDK
  • 受支持的 JRE(V1.4.2)
  • eRCP 运行库
    • 对于如今的里程碑构建版本(V1.0 GA),eRCP 支持三种平台:
      • Windows® Mobile 2003/Windows Mobile 5
      • Windows Desktop(Win32)
      • Nokia Series 80
    • 我们将使用前两种平台。下载 eRCP 里程碑程序包,用于 Windows 的标记为 Mx,其中 x 是里程碑号

对于小型设备,有一种不同规范的 Java™ 平台,称为 Java 2 Micro Edition(J2ME)。我们将使用 IBM® Workplace Client Technology 的 Foundation Profile 实现部分:Micro Edition for Windows。

总之,您需要如下软件:

  • Eclipse V3.2 和 JRE V1.4.2
  • 用于 Win32 和 Windows Mobile 2003/Windows Mobile 5 的 J2ME Foundation Profile
  • 用于 Win32 和 Windows Mobile 2003/Windows Mobile 5 的 eRCP 运行库

务必阅读安装部分中的安装步骤说明。

在开发机器上配置 Eclipse

  1. 运行 EclipseHome%\eclipse.exe
  2. 切换目标平台 —— 我们需要将默认的目标平台更改为根据正确的库构建和运行。单击 Window > Preferences,展开 Plug-in Development,然后单击 Target Platform。输入 eRCP 的位置(也就是 eRCP-v20060609-1423\win32\eRCP)并单击 Apply,再单击 OK
图 1. 切换目标平台
切换目标平台
切换目标平台
  1. 切换到 Plug-in Development 透视图(通过 IDE 右上角的选项卡)。

为在 Foundation Profile 上开发而设置工作空间

  1. 单击 Window > Preferences,然后选择 Java > Installed JREs
  2. 单击 Add 添加一个新的 JRE:

    JRE type 中,选择 Standard VM
    JRE name 中,提供一个恰当的名称,例如 Foundation 1.0
    JRE home directory 中,指向一个标准 J2SE JVM
    选择列出的全部 JRE system libraries,然后单击 Remove 来移除所有默认 JRE 系统库
    单击 Add External JARs ...,指向已安装的 Foundation Profile 库,如图 2 所示。
    • %WSDDhome%\wsdd5.0\ive-2.2\lib\charconv.zip
    • %WSDDhome%\wsdd5.0\ive-2.2\lib\jclFoundation10\classes.zip
    • %WSDDhome%\wsdd5.0\ive-2.2\lib\jclFoundation10\locale.zip
    • %WSDDhome%\wsdd5.0\ive-2.2\lib\jclFoundation10\map.zip
图 2. Foundation 1.0 JRE
Foundation 1.0 JRE
Foundation 1.0 JRE

更改编译器依从级别

Eclipse V3.2 将其默认的编译器依从级别设置为 5.0。而 eRCP 运行库是根据 1.4 构建的。我们必须手动在 Eclipse IDE 中将依从级别设置为 1.4。单击 Window > Preference,然后选择 Java > Compiler。将 Compiler Compliance Level 更改为 1.4,如图 3 所示。单击 Apply,再单击 OK

图 3. 编译器依从性设置
编译器依从性设置
编译器依从性设置

eRCP 应用程序构造块

eRCP 保留了继承自 RCP 动态插件模型的主要功能。在 eRCP 中,它支持两种应用程序模型:

独立 eRCP 应用程序
每个 JVM 一个 GUI 应用程序,它拥有自己的整个显示窗口。
工作台插件应用程序(eWorkbench)
应用程序在一个工作台窗口中同步运行,此窗口控制应用程序显示的位置和时间。仅需要一个 JVM。

我们将逐个介绍如何利用 Eclipse SDK 构建这两种模型。

eRCP 应用程序模型

eRCP 应用程序与普通 RCP 应用程序类似。每个 eRCP 应用程序都可以被视为一个插件,这是一个 OSGi 包,具有为 GUI 控件保留其自己的显示与 shell 的功能。Eclipse V3.2 提供了一个有用的模板,可用来创建简单的插件。让我们看看如何来更改一下这个模板,使之成为 eRCP 应用程序。

创建一个简单的插件

  • 单击 File > New > Project 打开 New 向导。
  • 选择 Plug-in Project 并单击 Next
  • Project Name 中输入 org.eclipse.testercp 并单击 Next
  • 看到问题 Would you like to create a rich client application? 时回答 Yes,然后单击 Next
  • 选择 Hello RCP 模板,然后单击 Finish

解析编译错误

完成上述步骤后,您会发现插件包含编译错误,如图 4 所示。

图 4. 编译错误
编译错误
编译错误
  • 从项目中删除 ApplicationActionBarAdvisor.java、ApplicationWorkbenchAdvisor.java、ApplicationWorkbenchWindowAdvisor.java 和 Perspective.java。在本例中,我们将使用 eSWT 的显示和 shell 作为 UI 控件的占位符。本例不涉及任何工作台、活动或透视图。
  • 在 MANIFEST 的 Imported Packages 中添加 org.eclipse.ui.plugin 和 org.eclipse.ui,如图 5 所示。它用来确保由 org.eclipse.testercp.Activator 扩展的 AbstractUIPlugin 得到解析。
图 5. 向 MANIFEST 进行手动添加
向 MANIFEST 进行手动添加
向 MANIFEST 进行手动添加

向 UI 添加内容

eRCP 应用程序维护其显示、shell 及所有 UI 控件和活动。eSWT 和 eJFace 是可在 eRCP/eWorkbench 应用程序中使用的主要 UI 组件。我们将使用一些 eSWT 代码来构造传统的 HelloWorld 应用程序。

表 1 列出了可在 eRCP 应用程序开发中使用的所有 UI 包。

表 1. eRCP 中的 UI 包
eSWTeJFace
org.eclipse.swtorg.eclipse.jface
org.eclipse.swt.browserorg.eclipse.jface.action
org.eclipse.swt.dndorg.eclipse.jface.operation
org.eclipse.swt.eventsorg.eclipse.jface.preference
org.eclipse.swt.graphicsorg.eclipse.jface.resource
org.eclipse.swt.internalorg.eclipse.jface.util
org.eclipse.swt.layoutorg.eclipse.jface.viewers
org.eclipse.swt.widgets-
  • 在 MANIFEST 的 Imported Packages 中添加 org.eclipse.swt、org.eclipse.swt.widgets、org.eclipse.jface.resource、org.eclipse.swt.graphics。
  • 对 Application.java 略加修改,使其与清单 1 类似。我们删除了与工作台相关的代码,但创建了一个 shell 和显示问候消息的文本。
清单 1. Hello eRCP
package org.eclipse.testercp;

import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * This class controls all aspects of the application's execution
 */
public class Application implements IPlatformRunnable {

  /* (non-Javadoc)
   * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)
   */
  public Object run(Object args) throws Exception {
    Display display = PlatformUI.createDisplay();
    Shell shell = new Shell(display, SWT.CLOSE);
    Label label = new Label(shell, SWT.NORMAL);
    label.setText("Hello eRCP!");
    label.setBounds(100, 80, 100, 20);
    shell.setSize(300,200);
    shell.setText("eRCP Application");
    shell.open();
       while (!shell.isDisposed()) {
          if (!display.readAndDispatch())
            display.sleep();
        }
        display.dispose();
        return IPlatformRunnable.EXIT_OK;
    
  }
}

运行

右击项目,单击 Run As > Eclipse Application,您将获得第一个 eRCP 应用程序。

图 6. eRCP 应用程序
eRCP 应用程序
eRCP 应用程序

eWorkbench 应用程序模型

eWorkbench 是 RCP 中一般工作台的重构实现。它是一个独立应用程序,拥有 JVM 的 GUI 线程,并管理所有 eWorkbench 应用程序的启动和显示。eWorkbench 可用作利用特定硬件特性的更为高级的工作台的基础。例如,具有多个显示屏的手机可以在手机外屏上显示有限的一些信息,在较大的显示屏上显示完整/正常的视图。eWorkbench 启动时,它会搜索可用的应用程序,并为用户提供一个列表,以便开始操作。用户也可以在 eWorkbench 应用程序之间进行切换,这些应用程序运行在一个 VM 实例中。这是通过 OSGi 框架包管理完成的。

与上一节类似,我们仍然可以利用 Eclipse 的模板,而不必从零开始。

创建一个简单的插件

  • 单击 File > New > Project 打开 new 向导。
  • 选择 Plug-in Project 并单击 Next
  • Project Name 字段中输入 org.eclipse.testworkbenchapp,并单击 Next,再单击 Finish

导入包

我们还必须手动导入所需的包,以解析编译错误,此外,还要添加在后续步骤中将用到的其他包。让我们来添加 org.eclipse.jface.resource、org.eclipse.swt、org.eclipse.swt.events、org.eclipse.swt.widgets、org.eclipse.ui.part 和 org.eclipse.ui.plugin。

图 7. 导入包
导入包
导入包

定义视图

接下来,我们需要为应用程序创建一个视图。当工作台启动一个应用程序时,它会将包含您的应用程序 UI 的视图显示在屏幕上。

  • 打开 MANIFEST.MF,切换到 Extensions 选项卡,然后单击 Add ...
  • Extension Point filter 中输入 org.eclipse.ui.views,然后您会看到 Sample Views 出现在 Available templates 中。选择模板并单击 Next,然后单击 Finish
  • 添加了两个扩展,我们只需要保留 org.eclipse.ui.views,因此删除 org.eclipse.ui.perspectiveExtensions。还要从 ui.views 扩展中删除 Sample Category(分类)。图 8 展示了当前的扩展列表。
图 8. 扩展 1
扩展 1
扩展 1

plugin.xml 中生成了一个该视图的扩展条目。让我们来看一下其中的字段及其所提供的信息是什么。

id
用于标识此视图的惟一名称。
name
一个可译的名称,将在 UI 中为此视图使用,在应用程序启动时,这个名称将作为应用程序的名称显示。
class
实现 org.eclipse.ui.IViewPart 的类的完全限定名称。一种常见的实践是子类化 org.eclipse.ui.part.ViewPart 以继承默认功能。
category
一个可选属性,由使用 “/” 分隔的分类 ID 组成。每个被引用的分类都必须在相应的分类元素中声明。
icon
一个将要与视图关联的图标的相对名称。

要获得各字段的更完整的说明,在 Extension 视图中选择 org.eclipse.ui.views 并单击 Open extension point description

清单 2. plugin.xml
   <extension
         point="org.eclipse.ui.views">
      <view
            category="org.eclipse.testworkbenchapp"
            class="org.eclipse.testworkbenchapp.views.SampleView"
            icon="icons/sample.gif"
            id="org.eclipse.testworkbenchapp.views.SampleView"
            name="Sample View"/>
   </extension>

一个 SampleView.java 也会添加到您的项目中,供您修改。再一次地,要实现一个简单的应用程序,应该在文件中删除除了 createPartControl(Composite parent)setFocus() 以外的所有一切。createPartControl 是视图的核心,这是我们为应用程序放置代码的地方。我们将复合体作为 parent 对象传递,并将 UI 放在其下。当工作台启动应用程序时,这些控件将被创建并显示出来。在清单 3 中,我们创建了一个 Label,并将其文本设置为问候语。

清单 3. SampleView.java
package sampleapp.views;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.part.*;
import org.eclipse.swt.SWT;

public class SampleView extends ViewPart {

  /**
   * The constructor.
   */
  public SampleView() {
  }

  /**
   * This is a callback that will allow us
   * to create the viewer and initialize it.
   */
  public void createPartControl(Composite parent) {
    Label myLabel = new Label(parent, SWT.BORDER|SWT.CENTER);
    myLabel.setText("Hello from SampleView!!!");
  }


  /**
   * Passing the focus request to the viewer's control.
   */
  public void setFocus() {
  }
}

定义您的工作台内容

创建一个简单应用程序的最后一步就是添加 org.eclipse.ercp.eworkbench.applications 的扩展。

  • 打开 MANIFEST.MF,切换到 Extensions 选项卡,然后单击 Add ...
  • 清除 Show only extension points from the required plug-ins,然后从列表中选择 org.eclipse.ercp.eworkbench.applications,再单击 Finish
  • 在弹出的 New plug-in dependency 对话框中回答 No。
  • 右击扩展并选择 New > application。plugin.xml 中将为此扩展点生成一个应用程序标记。
  • 在您的扩展中,将 id 更改为 org.eclipse.testworkbenchapp.application,将 name 更改为 Test workbench app。对于 singleton,将其设置为 true,这确保了在运行时此应用程序仅有一个实例存在。
  • 右击应用程序标记,选择 New > view。plugin.xml 中将在应用程序标记下生成一个视图标记。

图 9 列出了此项目中的扩展。

图 9. 扩展 2
扩展 2
扩展 2

接下来,让我们来看一下通过扩展 org.eclipse.ercp.eworkbench.applications 向 plugin.xml 添加了什么,以及这个扩展点中各字段的含义(参见清单 4)。

标记应用程序:

id
此应用程序的惟一标识符
name
此应用程序的人类可读名称

子标记视图:

normal
Normal 视图的标识符。Normal 视图是主要视图 —— 是应用程序正常工作所必需的,默认情况下会加载 Normal 视图。
large
Large 视图的标识符。Large 视图是可选视图 —— 它会在屏幕大小超过 480x640 时加载。
status
Status 视图的标识符。Status 视图是可选视图 —— 它用在具有多个显示屏的设备上的小显示屏中。

请注意,在 view 标记中要更改 normal 的值,使之与 views 扩展中的 id 属性相匹配,这非常重要。这对于应用程序的正常运行是至关重要的。在本例中,我们将其更改为 org.eclipse.testworkbenchapp.views.SampleView,如清单 4 所示。

清单 4. plugin.xml
   <extension
         point="org.eclipse.ui.views">
      <view
            category="org.eclipse.testworkbenchapp"
            class="org.eclipse.testworkbenchapp.views.SampleView"
            icon="icons/sample.gif"
            id="org.eclipse.testworkbenchapp.views.SampleView"
            name="Sample View"/>
   </extension>
   <extension
         point="org.eclipse.ercp.eworkbench.applications">
      <application
            id="org.eclipse.testworkbenchapp.application"
            name="Test workbench app"
            singleton="true">
         <views normal="org.eclipse.testworkbenchapp.views.SampleView"/>
      </application>
   </extension>

运行

运行 eWorkbench 应用程序与运行 eRCP 应用程序略有不同:

  • 单击 Run > Run ...,双击 Eclipse Application,这会为您创建一个新配置。
  • Name 更改为您喜欢的配置名称(例如 eWorkbench application)。
  • 切换到 Plug-ins 选项卡,选中 Choose plug-ins and fragments to launch from the list。确保您已选中了 Target Platform 中的所有插件以及您刚刚创建的 eWorkbench 插件。
  • 单击 Apply,再单击 Run,此时将显示 eWorkbench,如图 10 所示。
  • 单击 Test Workbench app,此时将为您显示上面创建的视图的 UI 控件,如图 11 所示。
图 10. eWorkbench
eWorkbench
eWorkbench
图 11. eWorkbench 应用程序的一个视图
eWorkbench 应用程序的一个视图
eWorkbench 应用程序的一个视图

定义您的首选项

您可以通过使类扩展 PreferencePage 来向应用程序添加首选项。这种由 eJFace 提供的特性允许用户存储以及从首选项存储中检索自己的首选项。首选项页是可选的。在使用它时,createContents() 方法是您放置代码的地方。通过使用这种复合体,它会作为控件的父控件传递给您。在用户启动您的应用程序并单击 Command > Preference 时,工作台将为首选项页显示一个多页对话框。要利用首选项存储,您需要扩展 org.eclipse.ui.preferencePages 扩展点,并提供一些信息(参见清单 5)。

id
表示您的首选项页的惟一标识符。
name
首选项页对话框中显示的首选项页名称。
class
实现了 org.eclipse.jface.preference.IPreferencePage 的完全限定类的名称。
category
一个路径,指明了页面在首选项树中的位置。路径可以是父节点 ID,也可以是使用 “/” 分隔的 ID 序列,表示根节点的完整路径。
清单 5. plugin.xml
   <extension
         point="org.eclipse.ui.preferencePages">
      <page
            class="org.eclipse.testworkbenchapp.preferences.SamplePreferencePage"
            id="org.eclipse.testworkbenchapp.preferences.SamplePreferencePage"
            name="Sample Preferences"/>
   </extension>

图 12 展示了当前您的列表中应该具有的扩展。

图 12. 扩展
扩展
扩展

清单 6 展示了首选项页的样本代码。

清单 6. 首选项样本
package mySample.app.preferences;

import java.io.IOException;

import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;


public class SamplePage extends PreferencePage {

  private static final String COLOR = "preference.Color";
  private static final String FOOD = "preference.Food";
  private static final String DRINK = "preference.Drink";
  private static final String COMEDY = "preference.Color";
  private static final String HORROR = "preference.Food";
  private static final String ACTION = "preference.Drink";
  
  private Text Color, Food, Drink;
  private Button check1, check2, check3;
  
  private PreferenceStore preferenceStore;
  Composite composite;  
  
  protected Control createContents(Composite parent) {
      composite = new Composite(parent, SWT.NONE);
      composite.setLayout(new GridLayout(2, false));

      preferenceStore = new PreferenceStore("mySample.properties");
      try {
        preferenceStore.load();
      } catch (IOException e) {}
      
      Label l = new Label(composite, SWT.LEFT);
      l.setText("Favorite Color:");
      Color = new Text(composite, SWT.BORDER);
      Color.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      Color.setText(preferenceStore.getString(COLOR));

      new Label(composite, SWT.LEFT).setText("Favorite Food:");
      Food = new Text(composite, SWT.BORDER);
      Food.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      Food.setText(preferenceStore.getString(FOOD));

      new Label(composite, SWT.LEFT).setText("Favorite Drink:");
      Drink = new Text(composite, SWT.BORDER);
      Drink.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
      Drink.setText(preferenceStore.getString(DRINK));
      composite.pack();
    
      Composite composite2 = new Composite(composite, SWT.NONE);
      composite2.setLayout(new RowLayout(SWT.VERTICAL));
      
      new Label(composite2, SWT.NONE).setText("Favorite movie type");      
      
      check1 = new Button(composite2, SWT.CHECK);
      check1.setText("Comedy");
      check1.setSelection(preferenceStore.getBoolean(COMEDY));

      check2 = new Button(composite2, SWT.CHECK);
      check2.setText("Horror");
      check2.setSelection(preferenceStore.getBoolean(HORROR));

      check3 = new Button(composite2, SWT.CHECK);
      check3.setText("Action");
      check3.setSelection(preferenceStore.getBoolean(ACTION));
    
      return composite;
  }

  public boolean performOk() {
    
    // save values
      if (Color != null) preferenceStore.setValue(COLOR, Color.getText());
      if (Food != null) preferenceStore.setValue(FOOD, Food.getText());
      if (Drink != null) preferenceStore.setValue(DRINK, Drink.getText());
      if (check1 != null) preferenceStore.setValue(COMEDY, check1.getSelection());
      if (check2 != null) preferenceStore.setValue(HORROR, check2.getSelection());
      if (check3 != null) preferenceStore.setValue(ACTION, check3.getSelection());
      
      try {
          preferenceStore.save();
        } catch (IOException e) {
          return false;
        }
     
      return true;
    }
  
  public boolean performCancel() {
    return true;
    }

}

要使代码被正确编译,您必须在 MANIFEST 中导入另外一些包,如图 13 所示。

图 13. 导入包
导入包
导入包

关于首选项页的注意事项

清单 6 中的代码使用了 PreferenceStore(String) 来创建或打开一个 PreferenceStore,参数 String 应该是该存储的惟一名称。使用 PreferenceStore.load() 从存储中检索数据。代码定义了惟一键,并将其与值配对。代码使用 preferenceStore.getString(key)preferenceStore.getBoolean(key) 检索值,并将其设置为恰当的字段。代码使用 preferenceStore.setValue(key, value) 以及 performOk() 中的 preferenceStore.save() 将值写入 PreferenceStore。这是在用户单击 Command > OK 来关闭首选项页时执行的。您可使用一个以上的首选项页,方法是扩展多个 org.eclipse.ui.preferencePages,并提供相应的实现。

图 14 展示了所显示的样本首选项页。

图 14. 首选项样本
首选项样本
首选项样本

如何为调试生成日志记录

RCP 平台提供了一个日志记录工具来记录异常、警告、任何服务敏感的事件,或者用于调试之目的。eRCP 平台中也提供了相同的日志记录工具。

每一个插件都有着自己的相关日志。但所有的日志信息最终都会聚集到一个平台日志文件中。可以通过 getLog() 来检索一个插件的日志。按照日志的严重程度提供了五个日志记录级别:

  • Status.OK
  • Status.INFO
  • Status.WARNING
  • Status.ERROR
  • Status.CANCAL

让我们利用之前的 eWorkbench 应用程序样本,来演示 Eclipse 日志记录的工作方式。

向插件添加三个重载 log 方法

清单 7 在 org.eclipse.testworkbenchapp.Activator 插件中创建了三个重载 log 方法。

清单 7. 重载 log 方法
import org.eclipse.core.runtime.Status;
...

public static void log(String msg) {
  log(msg, Status.INFO);
}

public static void log(String msg, int code) {
  log(msg, code, null);
}


public static void log(String msg, int code, Exception e) {
  getDefault().getLog().log(new Status(code, getDefault().getBundle().getSymbolicName(),
  code, msg, e));
}

在这里,实用工具类 Status 扮演着重要的角色。它利用五个参数将日志写入平台日志:

severity
表示严重程度 —— 可以是 OK、ERROR、INFO、WARNING 或 CANCEL
pluginId
相应插件的惟一标识符
code
特定于插件的状态码,也可以是 OK
message
人类可读的消息,已根据当前地区本地化
exception
一个低级异常,如果不适用,也可是 null

利用日志记录

performOk() 略作修改,如清单 8 所示,以便在保存时记录日志。日志记录将在正常的保存或异常出现时发生。

清单 8. 日志记录
import org.eclipse.core.runtime.Status;
...

      try {
          preferenceStore.save();
          org.eclipse.testworkbenchapp.Activator.log("Saved OK");
        } catch (IOException e) {
          org.eclipse.testworkbenchapp.Activator.log("Saved Fail",Status.ERROR,e);
          return false;
        }

检查日志

.log 文件是在 workspace/.metadata/.log 处生成的。如果控制台不可用,System.out 和 System.err 就无法使用。在此类环境下进行调试时,日志记录就很有优势。

如下代码展示了日志是如何放在 .log 文件中的。

!ENTRY org.eclipse.testworkbenchapp 1 1 2006-10-03 16:58:39.584
!MESSAGE Saved OK

部署到实际设备

上面差不多已经介绍了 eRCP 应用程序开发和调试的所有重要内容。在这一节中,我们将使用一种实际的设备:Windows Mobile 2003/Windows Mobile 5(eRCP 中支持的设备),以便演示部署是多么轻松。部署应用程序的基本理念是通过 Eclipse PDE 将其作为可部署插件导出,然后将插件 JAR 文件复制到设备的 eRCP 插件文件夹中。重启 eRCP 运行库,您会发现应用程序已作为一个新的 eWorkbench 应用程序条目列于其中。具体做法非常简单,您完全可以自己完成,因此此处不再赘述。我们将使用一种更为系统化的做法:通过更新管理器进行部署。

创建一个包含应用程序插件的特性

如果没有特性来包装一个插件,那么这个插件就无法通过更新管理器来安装。这也就是我们在这里创建特性的原因。创建一个特性的步骤与创建插件类似,因此不再详细说明。确保在 Referenced Plug-ins and Fragments 中选中了 org.eclipse.testworkbenchapp in。

清单 9 给出了 feature.xml。

清单 9. org.eclipse.testworkbenchapp.feature feature.xml
<feature
      id="org.eclipse.testworkbenchapp.feature"
      label="Test workbench application Feature"
      version="1.0.0">
...
   <plugin
         id="org.eclipse.testworkbenchapp"
         download-size="0"
         install-size="0"
         version="0.0.0"
         unpack="false"/>

</feature>

创建一个包含该特性的更新站点

要通过更新管理器安装一个应用程序,必须有一个更新站点,使用户能够进行浏览并开始安装。此外,已安装的特性应通过更新管理器进行管理,例如更新、禁用和删除。用户还可以通过更新管理器的 UI 查看特性的状态。

用户可以通过 Eclipse PDE 创建一个 Update Site Project,在其中还可以设置分类,如果组织一个站点时按应用程序的用途进行了分类(例如,运行时应用程序、样本应用程序、文档等),那么还应该可以向分类添加特性。

我们创建了一个名为 org.eclipse.testworkbenchapp.updatesite 的站点,具有一个分类 —— Test App,其中包含之前创建的特性。可以使用 Build All 来生成所需特性和插件,并将其放在您的站点项目中。

清单 10 展示了 site.xml。

清单 10. site.xml
<site>
   <feature url="features/org.eclipse.testworkbenchapp.feature_1.0.0.jar" 
   id="org.eclipse.testworkbenchapp.feature" version="1.0.0">
      <category name="Test App"/>
   </feature>
   <category-def name="Test App" label="Test App"/>
</site>

通过更新管理器进行安装

  • 确保 ActiveSync 连接已建立,设备已插入插槽。
  • 将整个 update site 文件夹(包含两个子文件夹:features 和 plug-ins)复制到 \My Documents 中。
  • 启动 eWorkbench 并单击 Application Manager
  • 单击 Install New Applications/Features
  • 单击 Command > Add Location,此时会显示一个对话框,要求您选择将特性安装到哪里,然后选择 LocalNext
  • 您将发现,会自动搜索我们刚刚放置的更新站点的 site.xml。单击 site.xml,然后单击 Finished
  • 现在,您有了一个更新的站点书签。选中站点并单击 Next
  • 站点搜索完成后,展开树,浏览此更新站点中的可用特性。选中 Test workbench application,再单击 Next
  • 选择 I accept the terms in the license agreemtns,然后单击 Next
  • 更新管理器将为您安装特性。一旦完成,将要求您重启运行库,以使更改生效。就 eRCP 而言,用户必须手动重启运行库。

您会发现,新应用程序安装在 eWorkbench 中,如图 15 所示。图 16 显示了在手持设备上运行的同一 UI。将图 16 与显示应用程序在台式机上的运行效果的图 11 相比较。

图 15. 设备上的 eWorkbench
设备上的 eWorkbench
图 16. 在设备上测试工作台应用程序
在设备上测试工作台应用程序

RCP 与 eRCP 应用程序之间的差异

从很大程度上来说,eRCP 是 Eclipse RCP 组件的子集。它包含核心运行库、eSWT、JFace、eUpdate Manager 和 eWorkbench,就像 RCP 组件包含非嵌入式 SWT、JFace、更新管理器和工作台一样。嵌入式版本与桌面版本之间的差异就在于移动设备相对于台式机的局限性。

除了移动设备有限的存储和处理能力之外,我们还需要考虑设备的 UI 和输入。eRCP 考虑了设备具有触摸屏还是仅有自定义功能键(softkey);它是否有键盘;有小显示屏、大显示屏还是兼而有之;在无法单击并拖动滚动条的情况下,设备是如何遍历一页上的小部件列表的。

在 SWT 具有的核心和扩展 UI 之上,eSWT 还包括了支持各设备的不同特性的移动扩展。简而言之,RCP 和 eRCP 之间的差异就在于嵌入式组件继承了 RCP API 的绝大部分,牺牲了某些功能以迎合移动环境,还添加了一些特定于个别移动设备特性的 UI 和 API。

结束语

我们已经逐步引导您完成了一次完整的 eRCP 应用程序开发。此外,还介绍了调试与部署。两个示例展示了如何编写独立 eRCP 应用程序和 eWorkbench 应用程序。更新站点样本描述了如何为 eRCP 平台应用正式部署。还提供了一些关于 RCP 与 eRCP 区别的要点,以及 eRCP 为什么能够以特定于设备的特性为目标。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source
ArticleID=194081
ArticleTitle=使用 Eclipse 开发 eRCP 应用程序
publish-date=02062007