本文由玉刚说写作平台提供写作赞助,版权归玉刚说微信公众号所有
原作者:AndroFarmer
版权声明:未经玉刚说许可,不得以任何形式转载
instant app 是谷歌推出的类似于微信小程序(或者说小程序类似于instant app)的一项技术,用户无须安装应用,用完就走,同时兼备h5的便捷和原生应用的优质体验。
工作方式:
应用场景:
4个模块
- app 类型:com.android.application
- base 类型:com.android.feature
- feature 类型:com.android.feature
- instantapp 类型:com.android.instantapp
传统方式创建一个项目,会生成一个app的模块,创建instant app 也会创建一个app模块,但功能跟传统的不太一样,传统的app模块基本上是整个项目的核心,所有的资源和代码实现都在这里,但instant app中app模块,充当的是传统app入口,具体代码实现交给base 和feature模块去完成同样的instantapp模块也是作为入口,它是作为instant app的入口。
我们来写一个例子,进一步介绍instant app
项目很简单,就是一个商品列表和商品详情
以instantapp方式运行看下运行效果(后面演示以app方式运行),多任务下显示一个闪电图标,代表这是一个instant app,并且在桌面找不到图标
在应用管理里面会多出 instant app的类别,在这里可以选择清除instant app 或者安装完整版app
打包过后,app模块下会生成app-debug.apk,instantapp模块下会生成 instantapp-debug.zip,并且 instantapp-debug.zip包含三个文件 :base-debug.apk,productlist-debug.apk,productdesc-debug.apk
我们可以根据需求在dependencies中配置让instantapp中打包一个或多个模块进去,但是base模块是必须的
上面的例子我们用了两个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);
看下运行效果
这样是可以打开,但是会弹出选择框让我们选择用哪个应用打开。要解决这个问题 我们可以在上面代码中加入这一句
it.setPackage(getPackageName());
前面我们说过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
关于deep links 这里就不做详细介绍了,大家可以搜索下资料还是挺多的,简单点来说,app links也属于 deep links,app links做了更严格的限制条件,以保证链接是安全可靠的
下面先看一张官方的两者之间的对比图
可以看到,app links对比deep links 做了更为严格的要求
看下我们例子中配置的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的规则了
要完成链接的验证我们有个需要有个站点,并且要在站点根目录配置一个”.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才可以。
好了最后附上一张 google trips 在应用市场的截图,install 左边有个 try now 这个就是instant app在应用商场上的入口