mengtuifrontend / Blog

芦叶满汀洲,寒沙带浅流。二十年重过南楼。柳下系船犹未稳,能几日,又中秋。 黄鹤断矶头,故人今在否?旧江山浑是新愁。欲买桂花同载酒,终不似,少年游。
18 stars 5 forks source link

Chrome 的新功能预览 - TWA #2

Open mengtuifrontend opened 5 years ago

mengtuifrontend commented 5 years ago

Chrome 的新功能预览 - TWA

在 APP 开发中,通常都会使用 webview 组件承载一个网页应用。最近 Chrome 团队宣称安卓 APP 可以直接使用 Chrome 浏览器全屏打开一个网页了。这种技术被称为 TWA (Trusted Web Activity)

为什么需要 TWA

TWA 基于安卓应用程序和网页站点属于同一开发者的信任前提,提供在应用内贡献 Chrome 浏览器中站点的资源,包括 cookie 等。

也就是当用户登陆了 Chrome 下的站点后,进入 APP 内打开站点可以获取到之前在 Chrome 中存储的状态。

这会给用户带来更好的一致性体验,而且,使用 TWA 的站点,可以全屏在 APP 内展示,没有浏览器的用户界面,但是同样享有 Chrome 浏览器的表单自动填充、共享 API 等功能。这些都是 Webview 无法提供的。

TWA 还具有一些特别的功能,比如发送网络推送通知、后台同步、媒体源扩展(MSE)和共享 API 等。

TWA 的标准

TWA 中的所有内容都必须符合 Play 商店政策,包括付款应用内购买和其他数字商品的政策。

TWA 必须符合安装 PWA 的标准,并且能够快速加载(Lighthouse性能评分 80 分以上)。也就是说,适用于 TWA 的站点首先是一个合格的 PWA 化的应用。

TWA 的内容受到保护,安卓应用程序无法读取或者修改其中内容。这也意味着只有应用程序通过查询字符串参数初始化站点时,可以将状态从应用程序共享至 TWA,而应用程序无法将内容插入 TWA。

在安装了 Chrome 的设备上可以使用 TWA,如果用户设备上的 Chrome 由于关闭更新是一个过期版本,那么 TWA 会自动替换成 Chrome 自定义标签(CCT)。因为本身 TWA 是一个 CCT 的特例(比 CCT 更好的使用 Chrome 的能力)。

如果站点的质量要求或者 Play 商店的政策修改都可能使 TWA 下架或者被拒绝入境。

受信认证与规避方式

TWA 通过数字资产链(DAL)认证用户是否可信任。

在测试的过程中可以设置设备上的 Chrome 跳过认证环节以便快速开发和测试。

  1. 在安卓设备中打开 Chrome 并进入 chrome://flags。搜索 Enable commmand line on non-rooted devices 并设置为启用(enable),然后多重启几次浏览器;
  2. 进入目录 /data/local/tmp/chrome-command-line,加入一份文件,内容为 _ --disable-digital-asset-link-verification-for-url="https://xxx.com",注意命令结尾处不要产生新行,不然会打开浏览器失败。

这样设置后启动 xxx.com 这个站点就会跳过受信认证了。

创建一个 TWA 应用

首页我们需要了解,TWA 应用首先是一个合格的 PWA 应用,所以应该在浏览器下得到充分的测试后才被用于 TWA。

安卓开发者需要确定使用的 SDK API 版本必须等于或高于 16

要创建一个 TWA 应用,可以按如下步骤。

创建项目

打开 Android Studio,创建一个 Android Studio project,点击下一步后会询问应用名称等,注意这里必须将最小 API 版本一项设置成不低于 API Level 16

加载类库

支持 TWA 的类库目前需要在 build.gradle 文件中配置 jitpack

allprojects {
  repositories {
    google()
    jcenter()
    maven { url "https://jitpack.io" }
  }
}

以后 TWA 类库会集成在 Jetpack 中,就不再需要上述的步骤了。

TWA 类库依赖 Java 8 的功能,所以需要确保在 Module 中启用 Java 8。在 Module 层级的 build.gradle 中加入 compileOptions 字段:

android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

然后就可以将 TWA 类库作为依赖项加入 dependencies 字段:

dependencies {
   implementation 'com.github.GoogleChrome.custom-tabs-client:customtabs:3a71a75c9f'
}

添加一个 TWA Activity

在应用的 AndroidManifest.xml 文件中添加一个 TWA Activity。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.twa.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity
            android:name="android.support.customtabs.trusted.LauncherActivity">

           <!-- Edit android:value to change the url opened by the TWA -->
           <meta-data
               android:name="android.support.customtabs.trusted.DEFAULT_URL"
               android:value="https://xxx.com" />

           <!-- This intent-filter adds the TWA to the Android Launcher -->
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>

           <!--
             This intent-filter allows the TWA to handle Intents to open
             airhorner.com.
           -->
           <intent-filter>
               <action android:name="android.intent.action.VIEW"/>
               <category android:name="android.intent.category.DEFAULT" />
               <category android:name="android.intent.category.BROWSABLE"/>

               <!-- Edit android:host to handle links to the target URL-->
               <data
                 android:scheme="https"
                 android:host="xxx.com"/>
           </intent-filter>
        </activity>
    </application>
</manifest>

这份 XML 文件中,有两个需要注意的地方:

  1. meta-data 标签用来描述 TWA 需要打开站点,可以通过修改 android:value 属性改变你需要打开的站点。
  2. 第二个 intent-filter 标签允许 TWA 拦截打开 https://xxx.comintent。确保这里 data 标签的 android:host 属性是 TWA 要打开的站点域名。

消除地址栏

TWA 需要和站点进行关联才能消除地址栏。

通过数字资产链(DAL),可以建立起应用程序和站点之间的关联。

上面已经叙述了如何跳过受信认证,这里讲一下如何设置 DAL。

在项目资源文件中打开 app > res > values > strings.xml,加上 DAL 声明:

<resources>
    <string name="app_name">XXX TWA</string>
    <string name="asset_statements">
        [{
            \"relation\": [\"delegate_permission/common.handle_all_urls\"],
            \"target\": {
                \"namespace\": \"web\",
                \"site\": \"https://xxx.com\"}
        }]
    </string>
</resources>

打开 AndroidManifest.xml 文件,在 application 标签内增加一个新的 meta-tag

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.twa.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="asset_statements"
            android:resource="@string/asset_statements" />

        <activity>
            ...
        </activity>

    </application>
</manifest>

这样我们建立起了应用程序和站点的关联。

接下来还需要建立站点和应用程序的关联,这里需要 2 个步骤。

  1. 第一个是需要应用程序的包名,这个可以从 Module 层级的 build.gradle 文件中找到。
  2. 需要 SHA-256 指纹,安卓应用必须签署后发布到 Play 商店,所以使用 SHA-256 指纹可以确保在站点和正确的应用程序之间建立关联。

完成这 2 步后就可以进入 DAL 生成器,填写字段并点击生成声明。复制生成的语句,确保可以在站点根目录下的 /.well-known/assetlinks.json 访问到。

打包

建立应用程序和站点的双向关联后,接下来就可以生成一个独立的 APP 了。

可以通过 adb 在一台连接的设备上安装应用。

adb install app-release.apk

如果发生错误,可以通过调试工具进行检查。

总结

TWA 在 PWA 基础上更加强化了用户体验一致性,即在 APP 内和浏览器内可以同步状态。而且 APP 内的站点还可以直接使用 Chrome 作为载体,享受比 webview 更多的特性。

在未来,如果 PWA 站点都可以十分方便的和 APP 进行集成的话,无疑会更加模糊 APP 和网页应用直接的边界。


Thanks