为 XO 笔记本开发 Mono 应用程序





5.00/5 (18投票s)
了解如何使用Sugar OS上的Mono为XO笔记本(OLPC项目的机器)开发应用程序。
摘要
本文将教你如何为Sugar和XO(OLPC项目机器)开发应用程序。更准确地说,在本文中,我将使用C#和Mono创建一个新的“活动”,它可以在XO和可下载虚拟机中包含的Sugar模拟器上运行。
引言
关于OLPC项目和XO
“每个孩子一台笔记本”协会开发了一种低成本笔记本电脑——“XO笔记本”——旨在彻底改变我们教育世界儿童的方式。OLPC项目的使命是通过为每个孩子提供一台坚固、低成本、低功耗、联网的笔记本电脑,并配有为协作、快乐、自主学习而设计的学习内容和软件,从而为世界上最贫困的儿童提供教育机会。
简而言之,XO是一台上网本。XO具有创新的硬件设计,带有双模显示屏——全彩透射模式和黑白反射模式(阳光下可读)。这些笔记本电脑配备433 MHz处理器和256 MB DRAM,以及1GB NAND闪存(没有硬盘)。这些笔记本电脑具有无线宽带功能,可与标准接入点配合使用,也可作为网状网络使用——每台笔记本电脑都能与其最近的邻居进行通信,创建一个临时局域网(基于802.11s标准)。这些笔记本电脑使用各种直流电源输入(包括发条和太阳能)。
内置Sugar
Sugar是XO笔记本的操作系统。Sugar学习平台促进协作和批判性思维学习。它已在全球800,000台分发给发展中国家的XO笔记本上使用。Sugar得到全球庞大的开发人员和教师社区的支持。Sugar不仅适用于XO笔记本,也适用于所有其他笔记本电脑。
从技术上讲,Sugar基于Fedora Core Linux和Gnome用户界面。然而,Sugar也可以在其他Linux发行版(Debian、Fedora、Mandriva等)上使用。
Sugar拥有独特的窗口管理器,概念简化,每个孩子都能很快理解。更重要的是,大部分界面可以由尚未学会阅读的儿童操作。
Mono
Mono项目是一个开放式开发倡议,旨在开发Microsoft .NET开发平台的开源版本。其目标是使Linux开发人员能够构建和部署跨平台.NET应用程序。该项目实现了Microsoft开发并提交给ECMA组织进行标准化的技术。
Mono不仅仅是一个“.NET克隆”。Mono带有一些独特的基于C#的组件、库和框架。其中最重要的是Gtk#,它允许用C#构建Gnome应用程序。Gtk#是Gtk+ GUI工具包的“绑定”。“绑定”一词意味着它允许直接从C#源代码调用本地库。
以下屏幕截图显示了一个使用命令行编译器的Mono基本示例。
如果你是一名.NET开发人员,这个示例应该看起来很熟悉。与.NET唯一的区别是,生成的*.EXE*文件不能直接在Linux上执行,因此你应该在命令行调用前加上*mono*。
创建你的第一个活动
Sugar化C#
Sugar主要用Python编写。Python是一种脚本语言,因此它是一个很好的工具,可以帮助用户自定义系统。如果你想创建新的应用程序(称为“活动”),Sugar将为你提供大量的Python API。
Torello Querci是Mono项目的贡献者。Torello一年前编写了一个C#/Sugar绑定,让你可以使用Mono创建Sugar活动。这个绑定被打包成一个名为*Sugar.dll*的.NET程序集。大多数Sugar API都可以从这个程序集调用。当然,这里描述的示例需要*Sugar.dll*程序集。
创建项目
要创建我们的第一个活动,我们将使用MonoDevelop。MonoDevelop是一个类似于Visual Studio的IDE。MonoDevelop允许你编辑和打包Mono应用程序。
开始吧
- 启动MonoDevelop(应用程序/编程/MonoDevelop)。
- 创建一个新解决方案(文件/新解决方案...),选择“C# / Gtk# 2.0项目”模板。
- 在表单中填写“LabActivity”作为名称。
我们使用Gtk#模板是因为Sugar基于Gtk。现在让我们配置这个解决方案以添加Sugar绑定。
我们只需要添加*Sugar.dll*程序集。右键单击引用,“编辑引用...”,选择“.NET程序集”选项卡,然后选择正确的程序集。
就这样,解决方案现在准备好了。
创建主窗口
以下是为活动创建主窗口的源代码
using System;
using System.Collections;
using Gtk;
using Sugar;
namespace LabActivity
{
public class MainWindow : Sugar.Window
{
public new static string activityId = "";
public new static string bundleId = "";
public MainWindow(string activityId, string bundleId)
: base("Lab", activityId, bundleId)
{
this.SetDefaultSize(400, 400);
this.Maximize();
this.DeleteEvent += new DeleteEventHandler(OnMainWindowDelete);
VBox vbox = new VBox();
vbox.BorderWidth = 8;
Label _text = new Label("Hello Lab Activity");
vbox.Add(_text);
Button _button = new Button();
_button.Label = "Quit";
_button.Clicked += new EventHandler(OnClick);
vbox.Add(_button);
this.Add(vbox);
ShowAll();
}
void OnMainWindowDelete(object sender, DeleteEventArgs a)
{
Application.Quit();
a.RetVal = true;
}
void OnClick(object sender, EventArgs a)
{
Application.Quit();
}
}
}
如果你是一名.NET WinForms开发人员,Gtk框架应该会让你感到熟悉。
MainWindow
的构造函数负责窗口初始化:它创建控件并设置事件处理程序。Sugar绑定增加了继承自Sugar.Window
类的需求,以便访问与Sugar API的底层通信。更准确地说,主窗口应该处理活动的标识符和实例的标识符。这两个值都发送给窗口管理器,并且应该从活动的入口点检索。具体方法如下
public static void Main(string[] args)
{
if (args.Length > 0)
{
IEnumerator en = args.GetEnumerator();
while (en.MoveNext())
{
if (en.Current.ToString().Equals("-sugarActivityId"))
{
if (en.MoveNext())
{
activityId = en.Current.ToString();
}
}
if (en.Current.ToString().Equals("-sugarBundleId"))
{
if (en.MoveNext())
{
bundleId = en.Current.ToString();
}
}
}
}
Application.Init();
new MainWindow(activityId, bundleId);
Application.Run();
}
现在我们可以构建并运行新应用程序:点击“项目/运行”。你应该得到这个
这是第一次成功:我们得到了第一个符合Sugar的C# Gtk应用程序。
Mono捆绑包
运行.NET应用程序的先决条件是必须安装.NET Framework。当然,Mono也是如此,你的机器上必须安装Mono。不幸的是,Mono不是XO上的标准软件包,我们不能强迫每个用户预安装它来运行我们的应用程序。
幸运的是,Mono在.NET中提供了一个独特的功能:将Mono打包成可执行文件的能力。这就是我们所说的“捆绑包”。
捆绑包允许您生成一个可执行文件,其中嵌入了执行它所需的所有内容:.NET Framework的程序集、用户程序集以及用于将MSIL翻译成适合处理器的机器代码指令的JIT编译器。
上一个图表显示了Hello World应用程序的捆绑包。在左侧,*.EXE*文件只是一个标准程序集。该程序集仅包含应用程序的MSIL代码,并在运行时使用JIT编译器和.NET Framework。在右侧,我们创建了一个Mono捆绑包。该捆绑包嵌入了JIT编译器,并且只需要.NET Framework程序集。运行时不再需要其他任何东西。
以下是您如何使用`mkbundle2`命令为Hello World应用程序创建Mono捆绑包的方法
当然,*hello.exe*程序集和*hello*捆绑包做的是同样的事情。请注意,*hello*捆绑包不再需要*mono*前缀,并且非常庞大(4MB,而初始程序集只有3KB!)。
我们示例活动的Mono捆绑包未在此处显示,但可以以相同的方式构建。
构建.XO文件
在OLPC Wiki的活动页面上,您可以找到所有可在XO笔记本上下载的活动。
以下屏幕截图显示了此页面的一小部分。如您所见,下载新活动意味着下载一个*.XO*文件。让我们看看什么是“.xo”文件以及我们如何生成此类文件。
像其他常见文件格式(*.JAR*、*.DOCX*等)一样,*.XO*文件是一个zip文件,其中包含活动所需的所有文件:二进制文件和资源文件。我们将在下面描述它。
*.XO*文件中最重要的文件是清单。清单应位于文件的根目录。以下是活动清单(名为`MANIFEST`)的内容
activity/activity-labactivity.svg
activity/activity.info
bin/libgdksharpglue-2.so
bin/libgladesharpglue-2.so
bin/libglibsharpglue-2.so
bin/libgtksharpglue-2.so
bin/libMonoPosixHelper.so
bin/libpangosharpglue-2.so
bin/labactivity-activity
bin/labactivity.exe
bin/uiX11Util.so
清单文件描述了*.XO*文件中的所有文件。*.XO*文件有两个目录:*activity*用于存放活动的属性,*bin*用于存放二进制文件。
二进制文件包括:活动的Mono捆绑包(*labactivity.exe*)、Gtk#共享库(*.so*文件)以及一个启动活动的Python脚本(*labactivity-activity*)。
Activity目录中的第一个文件是Activity的图标。此文件使用SVG格式。SVG是一种基于XML的矢量格式。此处使用的SVG文件只绘制了一个小方块
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY stroke_color "#666666">
<!ENTITY fill_color "#FFFFFF">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="55" height="55">
<rect x="5" y="5" width="45" height="45"
stroke="&stroke_color;" fill="&fill_color;" stroke-width="3.5"/>
</svg>
另一个重要的文件是*activity.info*文件。此文件包含活动的所有属性。这是我们的文件
[Activity]
name = LabActivity
activity_version = 1
host_version = 1
service_name = org.olpcfrance.LabActivity
icon = activity-labactivity
exec = labactivity-activity
mime_types =
*activity.info*文件只是一个文本文件,包含每个属性的值:名称、ID、图标文件的链接、启动脚本的链接等。
因此,总而言之,要创建*.xo*文件,您应该
- 启动Mono应用程序的构建
- 创建一个Mono捆绑包
- 构建一个包含所有二进制文件和配置文件的*.zip*文件
- 将文件从*.zip*重命名为*.xo*
项目源文件中包含的*deploy*脚本会自动构建*.XO*文件。您应该在每次构建结束时运行它。在脚本结束时,会生成一个*LabActivity-1.xo*文件
运行活动
我们的活动可以安装在Sugar模拟器上。本文随附的虚拟机中提供的Ubuntu桌面上有此模拟器的快捷方式。
一旦启动,Sugar模拟器将显示Sugar主页
要安装新的活动,首先点击终端活动(带美元符号的方块图标)。然后,在“.xo”文件上启动命令行*sugar-install-bundle*。此系统命令会解压软件包并添加活动。
活动的图标现在在桌面顶部可见(小白方块)。
点击图标启动我们的活动
请注意,Gtk控件在Sugar上与在Ubuntu上略有不同:按钮是圆角的。
如果您有幸获得了一台XO机器,您可以使用USB密钥安装活动,事先将*.XO*文件放入其中,或者如果您之前已将*.XO*文件部署到网站上,则使用浏览活动。结果窗口与模拟器中的完全相同。
让你的应用程序“Sugar化”
本文的前一部分展示了如何从头开始编写一个新的活动。或者,您可能对移植现有应用程序感兴趣。这就是我们所说的“Sugar化”应用程序。Torello Querci在将现有Mono Gbrainy应用程序“Sugar化”方面做得非常出色。Gbrainy是基于记忆的小游戏合集。以下屏幕截图展示了XO上的应用程序。
Gbrainy最初是用纯Gtk编写的。Gbrainy也是一个有趣的应用程序,因为它使用了两个高级Mono特性:Glade和Gettext。
Glade 是Gtk的窗口设计工具。Glade带有一个专门的设计工具,并使用基于XML的文件格式来存储资源。
Gettext 是 Gnome 的本地化工具。`Mono.Unix` 命名空间允许从您的 C# 应用程序调用 Gettext。请注意,Gettext 和 .NET 的标准本地化机制都可以从 Mono 中使用。Gettext 的主要优点是得到了庞大的开发人员社区的支持,并且与许多常见工具兼容,例如 Pootle 服务器或 Poedit 编辑器。
以下源代码来自Sugar化的Gbrainy应用程序。您可以看到Sugar特性、Glade属性的使用(`[Glade.Widget]`)以及对本地化方法的一些调用(`Catalog.GetString(...)`)。
public class gbrainy
{
[Glade.Widget("gbrainy")] Gtk.Window app_window;
[Glade.Widget] Box drawing_vbox;
[Glade.Widget] Gtk.Label question_label;
[Glade.Widget] Gtk.Label solution_label;
[Glade.Widget] Gtk.Entry answer_entry;
[Glade.Widget] Gtk.Button answer_button;
[Glade.Widget] Gtk.Button tip_button;
[Glade.Widget] Gtk.Button next_button;
[Glade.Widget] Gtk.Statusbar statusbar;
[Glade.Widget] Gtk.Toolbar toolbar;
GameDrawingArea drawing_area;
GameSession session;
const int ok_buttonid = -5;
ToolButton pause_tbbutton;
string activityId="";
string bundleId="";
public gbrainy (string [] args, params object [] props)
{
Catalog.Init ("gbrainy", Defines.GNOME_LOCALE_DIR);
IconFactory icon_factory = new IconFactory ();
AddIcon (icon_factory, "math-games", "math-games-32.png");
AddIcon (icon_factory, "memory-games", "memory-games-32.png");
AddIcon (icon_factory, "pause", "pause-32.png");
AddIcon (icon_factory, "resume", "resume-32.png");
AddIcon (icon_factory, "endgame", "endgame-32.png");
AddIcon (icon_factory, "allgames", "allgames-32.png");
AddIcon (icon_factory, "endprogram", "endprogram-32.png");
icon_factory.AddDefault ();
Glade.XML gXML = new Glade.XML (null, "gbrainy.glade",
"gbrainy", null);
gXML.Autoconnect (this);
Sugar.Activity activity =
new Sugar.Activity(app_window, activityId, bundleId);
activity.SetActiveEvent += activeChanged;
app_window.Show();
toolbar.IconSize = Gtk.IconSize.Dnd;
Tooltips tooltips = new Tooltips ();
ToolButton button = new ToolButton ("allgames");
button.SetTooltip (tooltips,
Catalog.GetString ("Play all the games"), null);
button.Label = Catalog.GetString ("All");
button.Clicked += OnAllGames;
toolbar.Insert (button, -1);
// ...
}
// ...
}
结论
本文是使用Mono进行Sugar开发的入门。Mono允许您利用您的.NET和C#技能为XO笔记本创建软件,为OLPC项目做出贡献,从而为世界上最贫困的儿童提供教育材料。何不抓住这个机会呢?
链接
本文来自SugarLabs wiki上的完整教程。法文版本也可在TechHead Brothers网站上获取。有关OLPC项目的更多信息,请随时与我联系。