什么是安卓Instant App(即时App)?
Chinese (Simplified) (中文(简体)) translation by Zhang Xiang Liang (you can also view the original English article)
每当你发布一个安卓APP时,你至少会想一下你想要这个APP实现什么目标。
你想要APP实现的目标应该非常具体,比如在第一季度产生一定的广告收入,或者在Google Play获取更高的排名。
甚至,你想要你APP实现的目标是想要尽可能多的用户使用你的APP,如果是这样,那么Instant Apps是能够帮你实现目标的新选择。
Instant App是一种全新的接触用户的方式,用户不需要在他们的设备上安装你的APP,而是在任何支持URL的地方(包括emails,Google搜索结果,社交平台上,YouTube的评论和论坛)找到并访问你的APP。
开发Instant App,你必须将你APP的功能划分为独立的模块。然后,用户点击你提供的URL,就可以加载这些模块中的任意模块而不需要下载你的APP。
在这个three-part系列,我将展示如何在安卓工程中添加对Instant App的支持。在这个系列的末尾,你将会创建一个APP,它包含两个独立的Instant App模块,你可以发布和测试它们。
我们即将讨论的内容
在这第一篇文章中,我们主要关注什么是Instant App,如何工作和你为什么需要关注它们。为了给你Instant App第一印象,我们将使用AS(Android Studio)创建工程时的选项来产生一个预先配置了支持Instant App的APP,所以你将能看到所有不同的Instant App组件而不仅仅是阅读它们。
尽管创建一个预先配置了支持Instant App的APP是使用这种新功能最快速最简单的方式,事实上你可能更喜欢给已经存在的工程添加对Instant App的依赖,而这在第二部分中展示。 我将提供一个APP,你可以从GitHub上下载,然后带你在这个工程一步一步添加对Instant App的支持。
最后是创建一个多功能的Instant App,所以在第三部分,我将展示如何给你的应用添加第二个功能模块,并且如何使用安卓APP链接来将这个模块映射到不同的URL。
什么是Instant Apps?
描述Instant App最好的方式之一是观察你可能用到的示例。
想象一下,你的一个朋友给你发送了一个关于小猫视频的链接,他们承诺你肯定会很喜欢,但是当你点击链接的时候,你才发现需要下载APP才能观看视频。
先不考虑你会不会下载APP,或者忽略那个链接,或者冒险在网络上找到那个小猫视频,这都不是好的用户体验,但却是许多安卓用户面临的场景。
我们大部分人都有过这样的体验,就是下载一个APP,然后仅仅完成单一的任务。比如,你可能下载一个APP仅仅是为了看一下别人发给你的email附件,来完成某个网站上的一次购买,或者跟踪一下你的包裹。
再次想象小猫视频案例,但是这次APP开发者已经把所有代码和资源放到instant app模块来播放视频,并且将该模块映射到网址www.example.com/video 这次,当你点击网址www.example.com/video,Google Play识别到这个网址与一个instant app 模块关联了,并且获取了所有用于播放视频的代码和资源。结果呢?你可以无需安装任何东西就可以观看20秒的小猫视频,多么棒的用户体验啊!
为什么我要开始使用Instant App特性?
正如你在这个系列的下一篇文章中看到的,给已有工程增加对Instant App的支持是烦人的,经常需要你完全改变应用的结构方式。
由于重构工程要很慎重,这部分我将帮助你决定你花费的时间和努力是否值得增加支持Instant App带来的收益。
- 消除APP与新用户之间的障碍通过Google Play安装一个APP不是特别困难和耗时,但是它仍然是你的APP与新用户之间的障碍。 无论你花费多少时间来吸引用户去点击那个Install按钮,仍然有许多人在点击那个瞬间放弃。
- Instant App有助于你的APP接触新用户。尽管你一直在网页的各种位置宣传你的APP,比如你自己的主页,博客或社交媒体,但连接新用户主要依赖他们访问你的APP的Google Play主页。 Instant app移除了这种对Google Play的依赖,在任意支持RUL的位置直接访问你的APP,给你接近无限制的机会来连接新用户。
- Instant App保证了分享的内容是你APP最好的广告。用户分享了你APP的内容是你APP接触新用户最好的方式,所以你要给人良好的第一印象。 之前,对于那些没有安装你APP的用户,为他们提供持续的体验是很困难的,但是现在Instant App可以保证丝滑原生的体验。
- 即使是在网络受限情况下,也能帮助用户访问你的APP。尽管网络吞吐量一直在改善,你仍然需要努力找到快速稳定的网络或者你正在接近每月的数据津贴,并担心会导致额外的费用。 当你的网络慢且不稳定时,下载一个完整的APP非常耗时麻烦,或者你随时可能超出流量上限,下载新的APP可能导致额外的费用。 所有的instant app模块必须小于等于4MB,所以如果下载整个APP不是问题,那么访问一个instant app也不是问题。
- 增加位置和时间敏感apps的吸引力。当APP被设计为特殊位置,或者甚至不是一个新概念,问问你自己,我有多想装一个只使用很短时间或只在某个特定位置使用的的APP? Instant app能增加时间和位置敏感APP的吸引力,因为用户只要点击一个URL就能访问你APP的最重要的功能。
限制
在我们开始instnat app之旅之前,我们需要知道instant app不能做到的事情:
- 访问设备标识符,比如IMEI和MAC地址。
- 使用后天服务
- 执行后台通知
- 访问设备外部存储
- 访问用户设备上已安装的APP列表-除非这些应用自己出现在instant app。
还有,你的应用必须:
- 你的应用可以免费从Google Play下载。
- 在Android 6.0(API 23)以上使用新的权限模式。由于用户没有安装instant app,没有机会申请权限。 假如你的instant app特性模块需要访问设备容量或用户信息,你需要动态申请权限。
- 支持APP链接。将instant app模块映射到指定URL。我将在下一篇文章详细讨论APP链接。
最后,假如你的APP是 Designed for Families的一部分,那么它不能作为instant app。
设置你的开发环境。
首先,你需要安装下列内容:
- AS 3.0预览版
- Android SDK 6.0
- Android SDK Build Tools 26.x
- Android SDK Tools 25.x
- Android SDK Platform Tools 25.x
你还应确保Android Support Library和Android Repository是最新的版本,打开Android Studio的SDK Manager,安装需要更新的地方。
一旦你完成上述所有操作后,就可以下载Instant Apps 的开发SDK:
- 打开SDKManager,然后选择“SDK Tools”选项卡。
- 选择Instant Apps Development SDK。
- 单击应用。
目前,您只能在Nexus 5X,Nexus 6P,Pixel,Pixel XL或Galaxy S7上测试Instant App,因为这些设备运行Android 6.0或更高版本的系统。但是,如果您没有这些设备中任意一台,那么您可以创建一个模拟其中一个设备的AVD(安卓虚拟机),而且AVD要满足几个条件:AVD必须使用x86映像,并且必须包含Google API 。
由于我没有这些设备,我将创建一个模拟Pixel的AVD:
- 启动AVD管理器。
- 单击Create virtual device... 按钮。
- 选择Pixel,然后单击Next。
- 选择x86 Images选项卡。
- 选择一个运行Android 6.0并包含Google API的系统映像,例如Marshmallow / 23 / x86 / Android 6.0(Google API)。
- 点击Next。
- 给您的AVD一个名称,然后单击Finish。
- 启动你的AVD。
最后,您需要在AVD上登录Google帐户:
- 切换到您的AVD,然后打开设备的启动器。
- 选择Google应用
- 输入Gmail地址和密码。这可以是您的真实账户,也可以是您创建的仅用于测试Android项目的帐户。
创建您的第一个Instant App
在Android Studio 3.0 Preview 1及更高版本中,创建具有内置Instant App的项目与选择复选框一样简单,所以,我们不仅仅是描述Instant App特性,我们还将创建一个Instant App项目,然后在本文的剩余部分体验它的各种组件。
请注意,该项目没有任何APP链接,所以您将无法在您的AVD上测试Instant App组件(这是我们将在第二部分中详细探讨的内容)。
创建您的项目:
- 通过从Android Studio工具栏中选择File > New > New project… ,或者从Android Studio的“欢迎”屏幕中单击Start a new Android Studio project ,来启动项目创建的引导页面。
- 给您的项目一个名称,然后单击下一步。
- 将Minimum SDK设置为Android 6.0(棉花糖)。
- 选中Include Android Instant app support 复选框,然后单击下一步。
- 为了简化操作,请接受默认模块名称(feature),然后单击下一步。
- 选择Basic Activity,然后单击下一步。
- 在下一个屏幕上,接受所有默认值,然后单击完成。
我们可以看到,这个项目与典型的Android项目结构非常不同,它包括以下模块:
- App。可安装的应用模块,也称为APK模块。
- Base。基本功能模块。
- Feature。虽然这个项目只有一个Feature,但一般一个APP由多个Feature模块组成。
- Instantapp。即时应用模块。



任何支持Instant app的项目都必须包含上述所有模块(除了feature模块),因此我们详细探讨这些模块。
1. Application Module
Application Module的概念可能不是什么新鲜事物,但是当您的项目支持Instant app时,应用程序模块的清单看起来比你曾经使用的更简洁:
1 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
2 |
package="com.jessicathornsby.myapplication.app" /> |
这个文件是如此空的一个原因是:当你建立你的项目时,所有其他的清单文件的内容包括base feature和 feature modules 都与这个文件合并,所以它不会永远保持这么空!
如果您打开此模块的build.gradle文件,则会注意到两个新元素:
1 |
dependencies {
|
2 |
implementation project(':feature')
|
3 |
implementation project(':base')
|
4 |
} |
在这里,我们声明我们的application module依赖于feature module 和 base module。
当你给项目添加对instant app的支持时,你就将相关代码和资源分离到可独立运行的feature modules。然后,这些模块仍然是可安装APP的一部分,而不是单独的实体,这就是为什么我们的application module声明依赖于feature module 和 base module。
2. Base Feature Module
每个instant app项目都必须包含一个base feature module,其中包含贯穿所有APP模块的代码和资源。例如,如果您打开项目的base / res / mipmap文件夹,那么您将看到所有应用程序的启动器图标,这些图标显然将被用于多个模块。



由于base feature module包含公共的代码和资源,所以所有项目的feature modules 都依赖于这个单一的base feature module。
继续这个主题,base feature module包含整个项目中使用的清单条目。例如,您的项目的base / src / main / AndroidManifest.xml文件包含应用程序的图标,主题和标签的设置:
1 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
2 |
package="com.jessicathornsby.myapplication"> |
3 |
|
4 |
<application
|
5 |
android:allowBackup="true" |
6 |
android:icon="@mipmap/ic_launcher" |
7 |
android:label="@string/app_name" |
8 |
android:roundIcon="@mipmap/ic_launcher_round" |
9 |
android:supportsRtl="true" |
10 |
android:theme="@style/AppTheme" /> |
11 |
</manifest>
|
另一个值得注意的元素是base module的build.gradle文件,其中包含一些新属性:
1 |
//All base feature and “regular” feature modules use the com.android.feature plugin, rather than the com.android.application plugin// |
2 |
|
3 |
apply plugin: 'com.android.feature' |
4 |
|
5 |
android {
|
6 |
compileSdkVersion 26 |
7 |
buildToolsVersion "26.0.0" |
8 |
|
9 |
//Specify that this is the project’s one and only base feature, using the ‘baseFeature true’ expression// |
10 |
|
11 |
baseFeature true |
12 |
… |
13 |
… |
14 |
… |
15 |
dependencies {
|
16 |
|
17 |
//Use ‘application project’ to add a dependency from the base feature module, to your project’s installable ‘app’ module// |
18 |
|
19 |
application project(':app')
|
20 |
|
21 |
//Use ‘feature project’ to reference our project’s feature module, aptly named ‘feature’// |
22 |
|
23 |
feature project(':feature')
|
24 |
您还会注意到,这个特殊的build.gradle文件缺少applicationID属性,当我们来检查我们的feature module的build.gradle文件时,您会发现完全相同的事情。这是因为我们项目的applicationID仅在应用程序模块的build.gradle文件中声明。
我们的base module的build.gradle文件中的application project(:app)行确保项目的单个applicationID属性在所有build.gradle文件中传播,这就是为什么我们项目的其余部分缺少此属性。
3. Feature Module
当您最终将Instant App支持添加到现有项目中时,最大的任务是将每个应用程序的特性提取到自己的feature module,中,因为每个feature module都包含仅提供此功能所需的代码和资源。
如果您打开我们项目的feature module,,那么您将看到它包含MainActivity类,以及activity_main和content_main资源文件 - 被引入到Basic Activity模板的所有组件。



单一的feature module可以由多个Activities组成,但每个模块必须至少有一个Activity被指定为该模块的入口Activity。
每个入口Activity被映射到特定的URL,当用户点击此URL时,它加载关联的Activity,然后用户访问此特定feature module。
您可以通过该模块的manifest指定模块的入门Activity。具体而言,您需要打开此manifest文件,并将以下内容添加到要作为入口的Activity中:
- 一个intent filter,具有
CATEGORY_LAUNCHER和ACTION_MAIN这两个intent。 - 包含关于URL(映射到入口Activity的URL)所有信息的
<data>元素。 -
android:autoVerify属性。这告诉系统检查您的应用程序是否有权作为该特定URL的默认处理程序。 这是一个重要的安全机制,它有助于保护网站所有者免受试图劫持其网址的恶意应用程序的攻击。
如果您打开我们的feature module的 manifest文件,那么您将看到所有这些代码已经添加到我们的MainActivity声明中:
1 |
<activity
|
2 |
android:name=".MainActivity" |
3 |
android:label="@string/app_name" |
4 |
android:theme="@style/AppTheme.NoActionBar"> |
5 |
<intent-filter android:order="1"> |
6 |
<action android:name="android.intent.action.VIEW" /> |
7 |
|
8 |
<category android:name="android.intent.category.BROWSABLE" /> |
9 |
<category android:name="android.intent.category.DEFAULT" /> |
10 |
|
11 |
<data
|
12 |
android:host="jessicathornsby.com" |
13 |
android:path="www.example.com/MainActivity" |
14 |
android:scheme="https" /> |
15 |
</intent-filter>
|
16 |
<intent-filter>
|
17 |
<action android:name="android.intent.action.MAIN" /> |
18 |
|
19 |
<category android:name="android.intent.category.LAUNCHER" /> |
20 |
</intent-filter>
|
21 |
<intent-filter android:autoVerify="true"> |
我们将在此模块中查看的最终文件是build.gradle文件,其中包含几行值得注意的代码:
1 |
//Again, we’re using com.android.feature plugin, rather than com.android.application// |
2 |
|
3 |
apply plugin: 'com.android.feature' |
4 |
|
5 |
android {
|
6 |
|
7 |
//As previously mentioned, this section is missing an ‘applicationID’ attribute// |
8 |
|
9 |
… |
10 |
… |
11 |
… |
12 |
dependencies {
|
13 |
implementation fileTree(dir: 'libs', include: ['*.jar']) |
14 |
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
|
15 |
exclude group: 'com.android.support', module: 'support-annotations' |
16 |
}) |
17 |
|
18 |
//All feature modules have a dependency on the base feature module, which we’re declaring here// |
19 |
|
20 |
implementation project(':base')
|
21 |
testImplementation 'junit:junit:4.12' |
由于所有feature modules都取决于base feature module,因此用户首次从应用程序请求任何功能时,都将会收到base feature module以及实际尝试访问的feature module。
请注意,尽管该特定项目由一个base feature module和一个feature module组成,但如果您的app仅仅有一个instant app可访问的feature时,则可以创建仅由base feature module组成的项目。 我们将在本系列中探讨instant app项目的“types”。
4. Instant App Module
Instant App module有一个简单的目的:它作为一个容器,将所有的feature modules 转换成instant app的APK。
如果您打开该项目的Instant App module,那么您将看到除了build.gradle文件外其他几乎是空的,它只是声明了对base feature module 和 feature module 的依赖关系:
1 |
apply plugin: 'com.android.instantapp' |
2 |
|
3 |
dependencies {
|
4 |
implementation project(':feature')
|
5 |
implementation project(':base')
|
6 |
} |
Testing Your App
由于此项目不包含任何APP链接,我们将无法测试其instant app组件,但我们仍然可以将该项目作为可安装应用程序运行。这可能不是特别令人兴奋,但是请记住,我们项目的大部分代码和资源位于instant app feature module中,重要的是测试我们的项目如何成为可安装的APP。
启动我们之前创建的AVD或将可兼容的物理Android智能手机或平板电脑连接到电脑,然后从Android Studio工具栏中选择Run > Run… > app 。
尽管我们所有的MainActivity代码都位于feature module中,但一旦我们的应用加载后,您将看到MainActivity的操作按钮(FAB)和Hello World消息。我们在这里看到的是我们的APP模块,它包含了分布在Instant App feature 和 base feature modules中的代码和资源,并且把它们结合到一个可安装的APP中。
结论
在本教程中,我们深入了解了Instant Apps的工作原理,并探讨了你需要为Android项目添加Instant App支持的各种原因。
在理想情况下,您开始探索Instant Apps的决定与开始新Android项目完全吻合,但不幸的是,作为开发人员很少这样方便!更多的情况是,您必须重新配置现有项目才能支持Instant Apps,这并没有在Android Studio的项目创建引导页中选中一个复选框那么简单!
在下一篇文章中,我们将深入了解如何为已有项目添加对instant app的支持。我还将向您展示如何实现App Links,因此在下一篇文章结束之前,您将创建一个功能齐全的instant app,并且您可以在任何兼容的AVD或Android设备上启动和测试instant app。
敬请关注!与此同时,请查看关于Android APP开发的其他文章。









