Android 版 Python
智能手机的移动应用开发非常热门。在 Android 领域尤其如此,这里的活跃程度通常是疯狂的。然而,当涉及到构建“真正的”Android 应用时,似乎只有一个编程选择:Java(尽管使用 Android 的 Native Development Kit 用 C/C++ 也是可能的,但需要做更多的工作)。即便如此,谷歌明智地选择了流行的 Java 编程技术作为其 Android SDK 的基础,该 SDK 运行一个定制的 VM。
总的来说,这是一个明智的策略,因为(与另一款流行的智能手机不同)无需拥有特定的硬件和软件即可开始 Android 上的应用开发。您只需要一台运行 Linux、Windows 或 Mac OS X 的 PC(或笔记本电脑),以及 Java 和免费的 Android SDK 的副本。谷歌为所有 Android 平台版本提供模拟器下载,甚至还有一个免费的 Eclipse 插件,可以帮助您入门并指明正确的方向。
这很棒——当然,前提是您是 Java 的粉丝。如果像我一样,您宁愿吃玻璃也不愿坐下来在 Eclipse 中编写一些 Java 代码,那么当您要在 Android 上实现您的下一个项目时,您似乎就倒霉了。但事实并非如此。有一个非常棒的项目叫做 Android 脚本层 (SL4A),它将脚本语言引入 Android 平台,并为 Java 开发提供了一个可行的替代方案。
在本文中,我将逐步介绍如何准备您的计算机以使用 SL4A 进行 Android 开发,然后展示如何在您的 Android 设备上编写、测试和运行一个用 Python 编写的简单脚本。
Android 脚本层是谷歌 20% 员工时间用于“个人项目”政策的直接结果之一。Damon Kohler 在谷歌工作,他创建 SL4A 是为了解决自己在 Android 编程方面的需求。SL4A 提供了一个与 Android 底层 Java 技术的高级接口,向脚本语言公开了 API 的一个子集。
Python 是 SL4A 上首批支持的语言之一,但也有为 Perl、JRuby、Lua、BeanShell、JavaScript 和 Tcl 贡献的解释器。在其默认状态下,SL4A 预装了一个可用的 shell 版本。SL4A 的 API 被设计为跨脚本语言可移植,因此如果您喜欢本文中的内容,但希望我使用 Perl 而不是 Python,那么我在此处使用的 API 调用应该与 Perl 解释器完全一样工作。的确,我非常喜欢 Perl,但我也同样精通 Python,而且,由于 Python 是 SL4A 的“标准”,我在本文中始终坚持使用 Python。请注意,您不必这样做。
要开始使用,您需要在您的计算机上运行 Android SDK 的副本,并且您需要一个 Java VM。尽管您不会使用 Java 编程您的 Android 应用,但您仍然需要一个 Java 运行时来执行 Android 模拟器,它是 SDK 的一部分。包含 Android 模拟器为您提供了一个沙盒测试平台,供您在创建应用时使用。
在继续之前,您需要确保您的 Linux 系统上安装了 Java VM。在我的系统上(运行最新的 Xubuntu),我输入了以下命令,并被告知这两个程序都不可用
$ javac -version $ java -version
Xubuntu 建议我可以使用 apt-get 安装 openjdk-6-jdk,这听起来对我来说很合理,所以我就是这样做的
$ sudo apt-get openjdk-6-jdk
如果您运行的发行版不是从 Debian 派生的,请在您的软件仓库中搜索类似的软件包,并在继续之前安装它。
安装好 Java 后,现在是时候获取 Android SDK 了。SDK 的下载适用于 Mac OS X、Windows 和 Linux。访问谷歌的 Android 开发者网站(见“资源”),获取最新的 Linux SDK tarball。
下载 SDK 后,只需在您选择的目录中解压 tarball 即可(您拥有的文件名可能与我在此处使用的文件名不同,但不用担心,您的可能是 SDK 的较新版本)
$ tar zxvf android-sdk_r07-linux_x86.tgz
此命令创建了一个名为 android-sdk-linux_x86 的新目录,我将其重命名为 Android。这个新创建的目录中有很多子目录。不要被里面的所有东西吓倒。在这个阶段,您只对一个子目录感兴趣,它叫做 tools。
在 tools 目录中,您只对两个程序感兴趣。adb 实用程序允许您将文件传输到(和从)您的 Android 模拟器(稍后详细介绍此实用程序)。android 工具允许您为当前 Android 版本的任意数量准备和运行模拟器,这就是您接下来要做的
$ cd Android/tools $ ./android
Theandroid命令启动 Android SDK 和 AVD Manager,这是一个为任意数量的 Android 虚拟设备创建 Android 模拟器的工具。目前,没有虚拟设备,因此您需要创建一个。但是,在此之前,您需要安装一个目标 Android API 包。要做到这一点,点击“Installed Packages”选项卡,然后按下“Update All”按钮。在出现的对话框中,点击“Accept All”,然后按下“Install”按钮。
由此产生的下载需要一段时间,所以请离开您的计算机,去厨房泡一杯咖啡。根据您的下载速度,您可能还有时间做一个简单的三明治。
下载完成后,让我们创建一个 Android 虚拟设备 (AVD)。AVD 是 Android 设备的虚拟版本,您可以在模拟器上运行它。选择“Virtual Devices”选项卡,然后点击“New”按钮。将出现一个对话框,您可以使用它来设置 AVD 的特性。图 1 显示我已为我的 AVD 命名(LJapp),选择了一个 API 目标(API Level 7,即 Android 2.1),并将我的虚拟 SD 卡设置为 256MB。当您做出选择后,点击“Create AVD”按钮以初始化您的 AVD。
如果您返回到“Virtual Devices”选项卡,您的 LJapp AVD 现在应该存在。选择 AVD 并按下“Start”按钮,然后从显示的对话框中选择“Launch”按钮。模拟器开始加载,几秒钟后,您将看到您的模拟 Android 设备的启动屏幕(图 2)。请注意,模拟器的运行速度比实际物理手机慢得多,因此可能需要一段时间才能进入 Android 启动屏幕。您的体验会因您的桌面处理器的速度而异。
注意:在本文的其余部分中,我使用“点击”一词来指代使用鼠标在模拟器中点击。您的物理 Android 设备上没有鼠标指针(那是您的手指的用途),但模拟器需要一些东西,因此鼠标指针“模拟”您的手指,因此使用“点击”一词来描述所需的动作。当您看到我使用“点击”一词时,请将其视为点击。
在您的模拟器上获取 SL4A 非常简单。首先点击 Android 浏览器,然后浏览到 SL4A 网站:code.google.com/p/android-scripting。
当 SL4A 网页出现时,点击方形图形(QR 码)以访问 SL4A 的下载 URL。下载应该立即开始,一旦完成,点击下载的软件包名称(在撰写本文时为 sl4a_r3.apk)以安装 SL4A。继续点击“Install”按钮,然后点击“Open”按钮以启动应用。系统会询问您是否参与使用情况跟踪(由您决定,这是可选的),然后 SL4A 会通知您在您的脚本列表中“未找到匹配项”。没关系;您尚未安装任何脚本。SL4A 现在已为 Python 做好准备。
返回到 Android 浏览器,双击屏幕以放大网页。在页面的右侧找到“Featured Downloads”部分,然后点击 python_for_android_r1.apk 链接旁边的下载箭头。和以前一样,让下载完成,然后再点击下载的文件以安装它。当您准备好后,点击“Install”按钮以确认安装解释器。当安装完成后,点击“Open”按钮,然后点击大的“Install”按钮以完成安装。Android 版 Python 应用会从 SL4A 网站下载、解压和安装 Python 支持文件,并将它们添加到 SL4A 中。整个过程应该只需一两分钟即可完成。如果花费的时间超过几分钟,请深吸一口气,记住模拟器比您的物理设备慢得多。
当安装完成后,您将看到一个“Uninstall”按钮。不要点击此按钮!如果您这样做,您将删除您刚刚安装的 Python 解释器。相反,点击模拟器的主页按钮(小房子图标)返回到 Android 主屏幕,点击屏幕底部的选项卡以查看已安装的应用列表,并注意 SL4A 已添加到您的模拟器中(图 3)。
继续点击 SL4A 图标,现在它会显示已安装的 Python 脚本列表。点击 hello_world.py 脚本会弹出 SL4A 运行菜单(图 4)。从左到右看,菜单图标的含义如下:1) 在 Python shell 中运行脚本,这在调试时很有用;2) “本地”运行脚本;3) 在 SL4A 的内置文本编辑器中编辑脚本,这仅对最微小的更改有用;4) 重命名脚本;以及 5) 删除脚本。要快速测试您的安装,点击第二个菜单图标,我喜欢将其称为“运行轮”。一两秒钟后,屏幕上会出现一条消息“Hello, Android!”,几秒钟后消失。

图 4. SL4A 菜单图标
如果它工作正常,点击 test.py 脚本,然后点击运行轮。这将运行一个运行时间较长的脚本,该脚本展示了作为在 Android 上工作的 Python 程序员可以使用的某些功能。同样,请记住模拟器运行缓慢,因此请耐心等待各种 Android 界面元素的出现。
您的 Android 模拟器现在已准备好运行您的自定义 Python 脚本,所以让我们创建一个。但在您这样做之前,请注意已发布的 SL4A API 是完整 Android API 的一个子集,因此某些功能要么不可用,要么正在使其可用,要么尚未完全支持(请参阅“资源”以获取当前列表的链接)。不要让这让您退缩。现有的功能足以用 Python 生成可用的 Android 应用。
为了感受 Python 在 SL4A 上的运行情况,让我们将一个现有的脚本移植到手机上。所讨论的脚本基于 O'Reilly Media 的 Head First Programming 第 2 章中的一些代码,该书是我在 2009 年与 David Griffiths 合著的。这个简单的脚本连接到一个名为 Beans'R'Us 的虚构公司的网站,以获取公司的主页并从页面的 HTML 中提取当前的咖啡豆价格。代码很简单,从服务器抓取 HTML 页面,搜索定价数据,从 HTML 页面中提取数据,然后在屏幕上显示出来
from urllib import urlencode from urllib2 import urlopen pg = urlopen("http://www.beans-r-us.biz/prices.html") text = pg.read().decode("utf8") where = text.find('>$') start_of_price = where + 2 end_of_price = start_of_price + 4 price = float(text[start_of_price:end_of_price]) print "The current price of coffee is:", price
这是 Python 2 代码,这是一个有意的选择,因为 SL4A 附带的 Python 是 2.6.2 版本。要运行此程序,请将其加载到 Python 的 IDLE 工具中,或从命令行执行它
$ python LJapp-cmd.py The current price of coffee is: 5.52
正如您所看到的,这个小脚本显示了当前发布的咖啡豆价格。
将此脚本变成 Android 应用只是决定您要使用的 Android UI 元素的问题,因为核心功能不需要更改。SL4A 上的 Python 功能齐全,因此您在标准 Python 中习惯使用的功能在您的智能手机上也可用。
为了使此脚本更像 Android 应用,让我们在启动时以及退出时显示一条友好的消息。makeToast() API 调用提供了此功能。
dialogCreateSpinnerProgress() API 调用允许您显示 Android 旋转对话框,前提是您随后记得调用 dialogShow() API 调用使其可见。让我们在从 Beans'R'Us 服务器请求网页之前显示一个旋转器,然后在我们处理完数据后使用 dialogDismiss() API 调用关闭旋转器对话框。并且,让我们在此时也振动手机,只是为了好玩。
为了结束脚本,使用 dialogCreateAlert()、dialogSetItems() 和 dialogSetPositiveButtonText() API 调用在 Android 对话框中显示豆子的价格。要退出,只需点击“OK”按钮。
以下是早期的 Python 代码,其中添加了对 SL4A API 的调用
import android from urllib import urlencode from urllib2 import urlopen app = android.Android() app.makeToast("Hello from LJapp") appTitle = "LJapp" appMsg = "Checking the price of coffee..." app.dialogCreateSpinnerProgress(appTitle, appMsg) app.dialogShow() pg = urlopen("http://www.beans-r-us.biz/prices.html") text = pg.read().decode("utf8") where = text.find('>$') start_of_price = where + 2 end_of_price = start_of_price + 4 price = float(text[start_of_price:end_of_price]) app.dialogDismiss() app.vibrate() appMsg = "The current price of coffee beans:" app.dialogCreateAlert(appMsg) app.dialogSetItems([price]) app.dialogSetPositiveButtonText('OK') app.dialogShow() resp = app.dialogGetResponse().result app.makeToast("Bye!")
除了添加 Android UI 代码外,早期代码不需要进行其他更改,只需删除早期脚本对 print 的调用(这不再需要)。
要将您的 Python 脚本传输到模拟器进行测试,请将您的代码文件复制到您的 Android 目录中,然后使用 tools 目录中的 adb 实用程序将您的文件推送到模拟器上的 SL4A scripts 目录
$ tools/adb push LJapp.py /sdcard/sl4a/scripts 6 KB/s (748 bytes in 0.116s)
文件传输完成后,检查 SL4A 中的脚本列表,并注意列表顶部附近添加了 LJapp.py。
继续,点击您的应用名称,然后点击运行轮。稍等片刻,您应该会看到旋转器对话框出现,同时您的脚本会联系 Beans'R'Us 网站并请求当前的咖啡价格(图 5)。不久之后,当前价格会出现在另一个对话框中(图 6)。恭喜!该脚本已移植到您的 Android 虚拟设备。
要在您的物理 Android 设备上运行 Python 脚本,请在您的手机上安装 SL4A 和 Android 版 Python,然后传输您的脚本。
要在您的物理 Android 设备上安装 SL4A,请在您设备的“应用程序”设置中启用“未知来源”选项。需要此设置才能在您的手机上安装非市场应用。完成此操作后,您可以按照您在模拟器上安装 SL4A 和 Python 时使用的相同步骤进行操作。为了稍微加快速度,请从 Android Market 安装条形码扫描器,并使用它来“读取”您桌面屏幕上的 QR 码。
有很多方法可以将您的脚本传输到真正的手机上。我发现使用蓝牙连接或 USB 电缆安排之类的东西的成功与否很大程度上取决于您运行的硬件。在一个手机上可行的方法,在另一个手机上就行不通,等等。您的体验可能会因您的实际设备而异。当需要传输文件时,我已经开始依赖一种解决方案,无论我使用哪种手机,它都能工作(只要手机可以连接到本地 Wi-Fi 网络)。我的做法是在我的运行 Linux 的开发 PC 上打开 OpenSSH 服务器,然后使用手机上的 AndFTP 文件传输应用来scp将文件从桌面传输到手机。AndFTP 可以从 Android Market 免费下载,并在几分钟内安装完毕。一旦我使用 AndFTP 连接到我的桌面,我就可以导航到我选择的目录,标记我想要的文件,然后将它们下载到我手机上的 SD 卡。
AndFTP 运行良好,我已经开始依赖它进行所有 Android 文件传输(参见“资源”)。只需确保将您的脚本传输到手机上的 /sdcard/sl4a/scripts,以确保您的脚本名称出现在 SL4A 脚本列表中。
将您的脚本文件传输到您的物理设备后,像以前一样启动 SL4A,点击您的应用名称,然后点击运行轮。正如预期的那样,您的应用运行方式与在模拟器上运行时完全相同,只是速度更快!我没有包含在真机上运行的应用的屏幕截图,原因有两个。首先,它看起来与在模拟器中完全相同,其次,它正在您的设备上运行,因此您可以在那里查看它!
SL4A 还有一个更深层次的功能可能会让您感兴趣。该项目包含关于创建独立的、可下载的 Android APK 包的草案说明(参见“资源”)。一旦创建,APK 文件会将您的自定义 Python 脚本与允许其他 Android 用户自动在其手机上安装 Android 版 Python,然后从智能手机的主菜单应用运行您的应用的信息捆绑在一起。描述创建 APK 的过程可能需要另一篇文章,所以我将其留给你们中勇敢的人去尝试 SL4A Wiki 上的说明。要查看和了解有关这样一个成功创建的 APK 的更多信息,请查看 Web 上的 Split Hitter(参见“资源”)。
在 Android 上,用 Java 编程您的应用不是唯一的选择。借助 SL4A,功能非常强大的脚本语言来到了 Android,将该平台提升到了一个新的可破解性水平。如果可以,请参与进来。人越多意味着关注越多,关注越多意味着更多的帮助和更多的代码。如果足够多的程序员参与进来,谷歌的官方支持将会到来,这只会帮助提高该项目在谷歌总部的知名度。SL4A 已经是一个很好的项目,我只能想象,如果谷歌赋予它“官方地位”,它将会成为一个多么伟大的项目。让我们希望这种情况尽快发生。
您可以从 SL4A 网站上托管的 wiki 文档中了解更多信息。请务必浏览 wiki 的“教程”部分,以获取其他人使用 SL4A 的链接。还有一个活跃的(并且非常友好的)SL4A 邮件列表,Damon 用它来宣布新版本、跟踪功能请求、报告补丁和传播关于 SL4A 的信息。如果您使用 SL4A 为 Android 构建了一个应用,请加入该列表,我将在那里见到您。
资源
谷歌 Android SDK:developer.android.com/sdk
SL4A 项目:code.google.com/p/android-scripting
SL4A API:code.google.com/p/android-scripting/wiki/ApiReference
AndFTP 主页:www.lysesoft.com/products/andftp/index.html
将 SL4A 脚本作为 APK 分享:code.google.com/p/android-scripting/wiki/SharingScripts
Split Hitter:www.splithitter.com
Paul Barry (paul.barry@itcarlow.ie) 在爱尔兰卡洛理工学院任教。他的最新著作是 Head First Python,由 O'Reilly Media 于 2010 年 11 月出版。在他的网站上了解更多关于 Paul 的信息:paulbarry.itcarlow.ie。