Android Intent: the UNIX pipe for GUI
UNIX 哲学中有很重要的一点,就是 pipe (管道) 的运用。正是由于管道的存在,才使得另一个著名的 UNIX 哲学成为可能:"Write programs that do one thing and do it well." 每个程序完成自己的工作,然后用管道串起来,然后多复杂的工作都能轻松搞定了。
但是 UNIX pipe 处理的是标准输入输出,因此只能用在 CLI 上。在 GUI 上一直没有类似的东西出现。 Apple 在 Mac 上做过 AppleScript 和 Automator 两个尝试,可以部分实现 UNIX pipe 的效果,但是它们使用起来都过于麻烦,需要太多的用户操作。
第一个在 GUI 上基本实现了 UNIX pipe 的,我觉得要算 Android 中的 Intent 接口。文档中的概括性介绍是这样的:
An intent is an abstract description of an operation to be performed.
Intent 是个贯穿 Android 核心的概念/接口,在 Android 中大部分的操作都是由一个 Intent 发起的。在桌面上点了个 Gmail 的快捷方式来 打开 Gmail?那其实是你的桌面程序 (Launcher) 发起了一个「我要启动 com.google.android.apps.gmail.MainActivity」的 intent 而已;在 Gmail 里菜单里面选了「选项」?那其实也是 Gmail 发起了一个「我要启动 com.google.android.apps.gmail.SettingsActivity」的 intent 而已。。。
当然这里举的例子跟 UNIX pipe 无关,咱们再来看下面几个例子:
我在 Google Currents 上看到了一篇不错的文章,想分享给朋友们。跟大多数 Android app 一样, Currents 里面也有个分享按钮的:
点了后会给出一个可以处理这个格式的内容的程序列表 (可以处理的程序太多,截图中只是其中一部分而已):
然后你可以选 Gmail:
或者 Google+:
或者 Twitter:
或者 Facebook, Path, 新浪微博,豆瓣说。。。只要你装了相应的程序,你就能分享到你想分享到的地方。
这里的分享动作就是一个 Intent。 Currents 只用管告诉系统说我这里有段文字要分享,然后后面的事情就完全不用操心了。系统自然会找出用户安装的所有可以用来分享文字的程序,让用户来选择自己想要的那个,然后把文字传给相应的程序,由程序来完成分享的工作。这样做的好处是什么?好处当然是 Currents 的程序员不需要在自己的程序里面写上一大堆分享到 twitter 的代码,分享到 google+ 的代码,分享到 facebook 的代码。。。
「什么?还有中国人用我们的程序?那我们是不是还得写分享到新浪微博和入人网的代码?」
「有日本用户抱怨我们不支持 mixi 了,咱是不是考虑加一下?」
...
iOS 5 说他们终于深度集成 twitter 了,在任何程序里面都可以直接分享到 twitter 了。但是其实 Android 从第一个版本开始,早就「深度集成」了所有社交网站了。。。
上面的例子是文字的,如果你要分享的是图片,体验也是相似的:
你看,你想用什么就能「深度集成」什么。在没有 Intent 的系统上,如果你不幸是个不像 Flickr 这么主流的图片站的用户,你能想象每个能输出图片的程序都写分享到 SmugMug 的代码么?
通过 Intent,你完全可以轻松完成任何图片处理流程,比如:拍照,分享到 Skitch 用红圈圈出重点,然后分享到 Facebook。
也正是因为如此,每个 Android app 都只需要管好自己的工作就行了。比如 Flickroid 就是一个优秀的 Flickr 上传工具,在早期版本中甚至在安装完后你都不能在 Launcher 中找到程序入口,因为它唯一的功能就是把图片上传到 Flickr,所以你只用在相册或者别的程序中把图片分享给 Flickroid 就行了。
"It just works."
分享只是 Intent 的无数种用法中的一种而已。除了分享外, Intent 还可以拿来干很多别的事情,比如要数据。Google Authenticator 是一个给 Gmail 或者别的账户生成登录时使用的基于时间的临时密码的程序。在设置账户的时候,需要扫描一个二维码,但是 Google Authenticator 完全不需要自己实现这个功能, Barcode Scanner 或者 Google Goggles 或者别的程序已经实现好了:
所以 Authenticator 只需要给系统一个 Intent 说我要扫一个二维码就行了。系统会让用户选择一个程序来完成这个工作 (或者如果只装了一个或者选过默认程序的话,直接打开那个程序),然后把扫描后的结果返回给 Authenticator。
btw, 昨天在网上看到一篇吹微信的文章,于是我去 Android Market 上看了一眼,结果就被截图震惊了 (原图在此,我这里留了个备份):
这群人能放着 Android 基于 Intent 的分享功能不用而用这种山寨 iOS 的实现,不得不说很符合腾讯一贯的山寨本色。