背景知識
eRCP 是作為一種將 Eclipse Rich Client Platform(RCP)的優勢應用到嵌入式設備之中的途徑出現的。涉及的主題有:
設置開發環境
eRCP 應用程序構造塊
如何為調試生成日志
部署到實際設備上
RCP 和 eRCP 應用程序之間的主要差異
設置開發環境
在 Windows 開發機器上安裝開發工具
最基本的 eRCP 開發環境包含以下組成部分:
Eclipse SDK
下載 Eclipse V3.2 SDK
受支持的 JRE(V1.4.2)
從 Sun Microsystems 或 IBM 下載運行庫
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。
WebSphere® Studio Device Developer
下載 WebSphere Studio Device Developer V5.7.1
為什麼需要使用 J2ME Foundation Profile for Win32
您已經有了 JRE V1.4.2 for Win32,您可能會好奇 Foundation Profile 是用來干什麼的。如果在開發過程中不使用相同的配置文件,那麼就要冒所使用的類在選定的 J2ME 配置文件中不可用的風險。因此,您很可能會得到一個在台式機上完美運行,但在某些設備上運行時,卻不斷拋出 ClassNotFoundException 的應用程序。建議您在開發和設備環境中使用 Foundation Profile。
總之,您需要如下軟件:
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
運行 EclipseHome%\eclipse.exe
切換目標平台 —— 我們需要將默認的目標平台更改為根據正確的庫構建和運行。單擊 Window > Preferences,展開 Plug-in Development,然後單擊 Target Platform。輸入 eRCP 的位置(也就是 eRCP-v20060609-1423\win32\eRCP)並單擊 Apply,再單擊 OK。
圖 1. 切換目標平台
切換到 Plug-in Development 透視圖(通過 IDE 右上角的選項卡)。
為在 Foundation Profile 上開發而設置工作空間
單擊 Window > Preferences,然後選擇 Java > Installed JREs
單擊 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
更改編譯器依從級別
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 進行手動添加
向 UI 添加內容
eRCP 應用程序維護其顯示、shell 及所有 UI 控件和活動。eSWT 和 eJFace 是可在 eRCP/eWorkbench 應用程序中使用的主要 UI 組件。我們將使用一些 eSWT 代碼來構造傳統的 HelloWorld 應用程序。
表 1 列出了可在 eRCP 應用程序開發中使用的所有 UI 包。
eSWT eJFace org.eclipse.swt org.eclipse.jface org.eclipse.swt.browser org.eclipse.jface.action org.eclipse.swt.dnd org.eclipse.jface.operation org.eclipse.swt.events org.eclipse.jface.preference org.eclipse.swt.graphics org.eclipse.jface.resource org.eclipse.swt.internal org.eclipse.jface.util org.eclipse.swt.layout org.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 應用程序
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
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
接下來,讓我們來看一下通過擴展 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
圖 11. 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(),
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
code, msg, e));
}
在這裡,實用工具類 Status 扮演著重要的角色。它利用五個參數將日志寫入平台日志:
severity 表示嚴重程度 —— 可以是 OK、ERROR、INFO、WARNING 或 CANCELpluginId 相應插件的惟一標識符code 特定於插件的狀態碼,也可以是 OKmessage 人類可讀的消息,已根據當前地區本地化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,此時會顯示一個對話框,要求您選擇將特性安裝到哪裡,然後選擇 Local 和 Next。
您將發現,會自動搜索我們剛剛放置的更新站點的 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
圖 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 為什麼能夠以特定於設備的特性為目標。
本文配套源碼