instant app入门与开发指南

本文由玉刚说写作平台提供写作赞助,版权归玉刚说微信公众号所有
原作者:AndroFarmer
版权声明:未经玉刚说许可,不得以任何形式转载

概述

instant app 是谷歌推出的类似于微信小程序(或者说小程序类似于instant app)的一项技术,用户无须安装应用,用完就走,同时兼备h5的便捷和原生应用的优质体验。

工作方式和应用场景

工作方式:

  • 当用户点击链接时,通过applink去打开相应的instant app,如果之前没有打开过,则会从play store去下载并打开,整个过程一气呵成,跟浏览器打开网页,如果有缓存先读缓存,没有就去服务器loading一样

应用场景:

  • 通过直接点击链接进入(从社交网络或短信中点击链接)
  • 通过浏览器搜索,如搜索X电商的y商品,通过点击浏览器的搜索结果可直接进入instant app
  • 通过google play 可以先试用部分功能,觉得不错再安装完整功能
  • 在游戏中方面的应用,跟上面类似,更偏相向于试玩

如何创建模板Demo

  • 创建一个project
  • 当走到选择form和sdk版本时,勾选 “include android instant app support“


    image
  • 如果没有安装相应support,去sdktools下安装


    image
  • 填写apps link 相关的url 参数,这里作为创建演示用默认值就好


    image
  • 项目创建完成后会生成4个模块


    image

    至此一个模板instant app创建过程就完成了

项目结构

4个模块

  • app 类型:com.android.application
  • base 类型:com.android.feature
  • feature 类型:com.android.feature
  • instantapp 类型:com.android.instantapp

2个入口

  • app
  • instantapp


    image

项目解析

传统方式创建一个项目,会生成一个app的模块,创建instant app 也会创建一个app模块,但功能跟传统的不太一样,传统的app模块基本上是整个项目的核心,所有的资源和代码实现都在这里,但instant app中app模块,充当的是传统app入口,具体代码实现交给base 和feature模块去完成同样的instantapp模块也是作为入口,它是作为instant app的入口。

  • 模块间的关系图


    image

    image

    image
  • 模块间的关系总结
  1. 模块app 和instantapp 一般作为入口不负责具体的代码实现
  2. base模块和feature模块都可以做具体逻辑实现,base侧重公用部分的代码实现和公共资源的存放,feature则侧重于独立模块功能的实现
  3. base模块有且只有一个
  4. feature可以没有或有多个
  5. feature与base的gradle文件差异


    image

    image

    可以看到feature可以通过 声明 “ baseFeature true” 变成basefeature

写一个例子

我们来写一个例子,进一步介绍instant app
项目很简单,就是一个商品列表和商品详情


image

以instantapp方式运行看下运行效果(后面演示以app方式运行),多任务下显示一个闪电图标,代表这是一个instant app,并且在桌面找不到图标


image

在应用管理里面会多出 instant app的类别,在这里可以选择清除instant app 或者安装完整版app
image

打包过后,app模块下会生成app-debug.apk,instantapp模块下会生成 instantapp-debug.zip,并且 instantapp-debug.zip包含三个文件 :base-debug.apk,productlist-debug.apk,productdesc-debug.apk

我们可以根据需求在dependencies中配置让instantapp中打包一个或多个模块进去,但是base模块是必须的


image

image

多个feature间的数据交互

上面的例子我们用了两个feature:productlist,productdesc,他们之前是如何进行交互的呢。
先来看下他们俩的dependencies
productlist:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation project(':base')
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

producdesc:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':base')
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

可以看出,他们都依赖base模块,但相互之间没有关系。当然我们可以在productlist中去implementation project(':producdesc') 这样可以可以访问producdesc模块了,但是这不符合instant app 模块化设计的思路了,这样就没法根据需求app和installapp 只打包各自需要的模块了,这里我们可以使用deep links,通过隐式的intent去打开productdesc,这样模块之间就可以解耦访问了
这里先看下我的例子中deep links的配置,后面会详细介绍

        <activity android:name=".ProductDesc" android:label="商品详情">
            <intent-filter >
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:host="androfarmer.com"
                    android:path="/productdesc"
                    android:scheme="https" />
            </intent-filter>
        </activity>

那么根据我们的deep links 去写intent如下

  Intent it=new Intent();
                it.setAction(Intent.ACTION_VIEW);
                it.addCategory("android.intent.category.BROWSABLE");
                it.addCategory("android.intent.category.DEFAULT");
                it.setData(Uri.parse("https://androfarmer.com/productdesc"));
                it.putExtra("data",datas.get(position));
                ActivityCompat.startActivity(ProductList.this,it,null);

看下运行效果


image

这样是可以打开,但是会弹出选择框让我们选择用哪个应用打开。要解决这个问题 我们可以在上面代码中加入这一句

                it.setPackage(getPackageName());

这样就可以不出先弹窗直接进入productdesc页面了


image

前面我们说过instant app是可以通过链接直接打开app,没有弹窗,但是我们从外部链接打开的话不可能知道我们的app的包名,所以一旦我们的intent无法从系统中所有的app找到唯一值的化,系统就会弹出框让我们选择哪一个app打开,要做到从外部无弹窗打开就需要用到app links。
以下是用adb 命令模拟从外部打开应用的情况

 adb shell am start -W -a android.intent.action.VIEW -d https://androfarmer.com/productlist
image

App Links

关于deep links 这里就不做详细介绍了,大家可以搜索下资料还是挺多的,简单点来说,app links也属于 deep links,app links做了更严格的限制条件,以保证链接是安全可靠的

下面先看一张官方的两者之间的对比图


image

可以看到,app links对比deep links 做了更为严格的要求

  • scheme只能是http 或https
  • action必须android.intent.action.VIEW
  • category必须包含 android.intent.category.BROWSABLE 和 android.intent.category.DEFAULT
  • 系统版本有最低6.0的要求
  • 需要数字资产链接文件完成链接的验证(下面介绍)

看下我们例子中配置的app links

     <activity android:name=".ProductList"  android:label="商品列表">
            <intent-filter
                android:autoVerify="true" >
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:host="androfarmer.com"
                    android:path="/productlist"
                    android:scheme="https" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

android:autoVerify="true" 这个标明,它是自动验证的, 把这个去掉就符合deep link的规则了

Link Verfication(数字资产链接验证)

要完成链接的验证我们有个需要有个站点,并且要在站点根目录配置一个".well-known" 文件夹,文件夹中需要配置一个名为”assetlinks.json“数字资产链接文件,
文件内容的格式如下:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target" : { "namespace": "android_app", "package_name": "com.androfarmer.instant.app",
               "sha256_cert_fingerprints": ["0E:2E:C0:8B:99:AA:F3:51:4C:EF:A5:14:A6:B9:0E:EA:85:FD:A6:F6:AB:A2:40:DB:27:C9:45:2E:8F:4E:97:D6"] }
}]

最终要保证在浏览器上测试 https://domain.name/.well-known/assetlinks.json 这个数字资产链接文件可以正常访问
domain.name替换成你的站点域名,并且要与我们app中配置的app links域名一致
assetlinks.json文件通过 https://developers.google.com/digital-asset-links/tools/generator 官方站点去生成和验证,一定要通过验证才能使用。

也可以直接在上面的基础上修改 package_name 和 sha256_cert_fingerprints的值,这两个值 也就是我们app的application id和签名文件的sha256值
经过这个步骤以后,我们再通过链接去打开我们的app就不会出现选择弹窗直接打开我们的app了。由于条件不允许(没有个人站点),这里就不演示了
如果要体验完整的instant app流程的话 还需要将app 和instant app的包都上传到google的play store才可以。

Tips & Suggestion

  • 要使用模拟器测试instant app,最好使用 Android 8.1以上系统,并且必须硬件架构选择x86 不能是x86_64
  • App Links Assistant 可以帮助我们生成app links 工具在as菜单栏tools下找到
  • assetlinks.json 可配置一个站点关联一个或多个app,或者一个app关联多个站点,具体详见官方链接https://developer.android.com/training/app-links/verify-site-associations
  • instant app 可以使用的权限:
  • ACCESS_COARSE_LOCATION
  • ACCESS_FINE_LOCATION
  • ACCESS_NETWORK_STATE
  • BILLING
  • CAMERA
  • INSTANT_APP_FOREGROUND_SERVICE (API level 26 or higher)
  • INTERNET
  • READ_PHONE_NUMBERS (API level 26 or higher)
  • RECORD_AUDIO
  • VIBRATE
  • 对于已经发布应用市场的instant app 可以通过调用 showInstallPrompt() 去引导用户安装完整版的app
  • 可以调用 isInstantApp()查看是否是instant app 这对于权限判断比较重要,比如你的app和instant app共用feature的情况
  • instant app 不能脱离完整版的app 必须先上传app 才能上传instant app
  • instant app 单个feature的大小限制是4MB,但没有总大小的显示,所以如果项目体积比较大可以通过多feature方案解决

好了最后附上一张 google trips 在应用市场的截图,install 右边有个 try now 这个就是instant app在应用商场上的入口


image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271