预热和预提取:使用自定义标签页服务

塞巴斯蒂安·本茨
Sebastian Benz

本指南的第三部分重点介绍如何通过 warmup() 加快浏览器启动速度以及通过 mayLaunchUrl() 预提取网页。在打开链接时,浏览器进程的预热时间最长可节省 700 毫秒。通过 mayLaunchUrl 预呈现内容,可立即打开外部内容。将这两种 API 结合使用可以显著改善自定义标签页集成的用户体验,因此强烈建议您使用。

必要步骤如下:

  1. 请通过 CustomTabsClient.getPackageName(...) 检查是否默认浏览器支持自定义标签页。如果是,请通过 CustomTabsClient.bindCustomTabsService() 绑定到 CustomTabsService。
  2. 连接到 CustomTabsService 后,请在 CustomTabsServiceConnection.onCustomTabsServiceConnected() 回调中执行以下操作:

    a. 通过 CustomTabsClient.warmup() 预热浏览器进程。b. 通过 CustomTabsClient.newSession() 创建一个新的 CustomTabsSession

  3. (可选)预提取用户可能会通过 CustomTabsSession.mayLaunchUrl() 访问的网页。

  4. 启动新的自定义标签页时,通过 new CustomTabsIntent.Builder(session) 构造函数将 CustomTabsSession 传递给 CustomTabsIntent.Builder

如果您的应用以 Android API 级别 30 为目标平台,CustomTabsClient.getPackageName(...) 会要求您在 Android 清单中添加一个查询部分,以声明一个 intent 过滤器,使其与支持自定义标签页的浏览器相匹配。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
  …
   <queries>
        <intent>
            <action android:name="android.support.customtabs.action.CustomTabsService" />
        </intent>
    </queries>
</manifest>

以下是有关如何连接到自定义标签页服务的完整示例:

private CustomTabsClient mClient;
private CustomTabsSession mSession;

private CustomTabsServiceConnection mConnection = new CustomTabsServiceConnection() {
    @Override
    public void onCustomTabsServiceConnected(
            @NonNull ComponentName name,
            @NonNull CustomTabsClient client
    ) {
        mClient = client;
        // Warm up the browser process
        mClient.warmup(0 /* placeholder for future use */);
        // Create a new browser session
        mSession = mClient.newSession(new CustomTabsCallback());
        // Pre-render pages the user is likely to visit
        // you can do this any time while the service is connected
        mSession.mayLaunchUrl(Uri.parse("https://developers.android.com"), null, null);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mClient = null;
        mSession = null;
    }
};

private void bindCustomTabService(Context context) {
    // Check for an existing connection
    if (mClient != null) {
        // Do nothing if there is an existing service connection
        return;
    }

    // Get the default browser package name, this will be null if
    // the default browser does not provide a CustomTabsService
    String packageName = CustomTabsClient.getPackageName(context, null);
    if (packageName == null) {
        // Do nothing as service connection is not supported
        return;
    }
    CustomTabsClient.bindCustomTabsService(context, packageName, mConnection);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
…
    bindCustomTabService(this);
    findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String url = "https://developers.android.com";
            CustomTabsIntent intent = new CustomTabsIntent.Builder(mSession)
                    .build();
            intent.launchUrl(MainActivity.this, Uri.parse(url));
        }
    });
}

在原生应用中打开网页

在 Android 上,网址可由原生应用处理。例如,如果用户安装了 Facebook 应用并点击了 Facebook 帖子的链接,则他们通常更希望点击在 Facebook 应用中打开的链接,而不是在浏览器中打开。

默认情况下,如果已安装“自定义标签页”,则“自定义标签页”会在相应的原生应用中打开链接。不过,一旦建立了 CustomTabsServiceConnection,此行为就会停止运行,并改为在自定义标签页中打开所有网址。为了改善用户体验,我们建议您使用以下代码重新启用此行为:

CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder()
    .setSendToExternalDefaultHandlerEnabled(true)
    .build();

接下来:了解如何调整自定义标签页的大小