Android开发小工具之:Chrome Custom Tabs

一、为什么要用Chrome Custom Tabs?

当App需要打开一个网站时,开发者面临两种选择:默认浏览器或WebView。这两种选择都有不足。从App跳转到浏览器是一个非常重的切换,并且浏览器无法自定义;而WebView无法与浏览器共享cookies等数据,并且需要开发者处理非常多的场景。

Chrome Custom Tabs提供了一种新的选择,既能在App和网页之间流畅切换,又能有多种自定义选项。其实它本质上是调用了Chrome中的一个Activity来打开网页,这样想就能理解这些优点了。能自定义的项目有:

  • ActionBar(也就是最上面的 Toolbar,网址一栏)的颜色

  • 自定义 Tab 的进入和退出过场动画

  • 在自定义 Tab 的 ActionBar 上添加自定义图标和菜单

  • 自定义返回图标

  • 自定义 Tab 可以通过回调接口来通知应用网页导航的情况

  • 性能更好,使用 Custom Tab 来打开网页的时候,还可以预先加载网页内容,这样当打开的时候,用户感觉非常快。

  • 生命周期管理,使用 Custom tab 可以和您的应用绑定一起,当用户在浏览网页的时候,您的应用也被认为是互动的程序,不会被系统杀死。

  • 可以共享 Chrome 浏览器的 Cookie ,这样用户就不用再登录一遍网站了。

  • 如果用户开启了 Chrome 的数据压缩功能,则一样可以使用

  • 和 Chrome 一样的自动补全功能

  • 只需点击左上角的返回按钮一次就可以返回您的应用中了

  • 每次用的都是最新版本的 Chrome

Chrome Custom Tabs还提供预启动Chrome和预加载网页内容的功能,与传统方式相比加载速度有显著提升。下图是一个使用 Chrome 、Chrome Custom Tabs 和 WebView 来打开同一个网页速度的对比:

二、什么时候用Chrome Custom Tabs,什么时候用WebView?

如果Web页面是你自己的内容(比如淘宝商品页之于手机淘宝),那么WebView是最好的选择,因为你可能需要针对网页内容及用户操作做非常多的自定义。如果是跳到一个外部网站,比如在App中点了一个广告链接跳转到广告商的网站,那么建议使用Chrome Custom Tabs。

当然,用户的手机上需要安装Chrome 45 或以上版本,并且设为默认浏览器。考虑到Chrome在国内手机上的占有率,这确实是个问题......但如果你的APP不只是面对国内市场,那么以Google在海外市场的影响力,这完全不是问题。

肯定有人要问,如果手机上没有装Chrome,调用Chrome Custom Tabs会发生什么行为呢?我们查看CustomTabsIntent.Builder源码可以发现,Builder的内部构造了一个action为Intent.ACTION_VIEW的Intent,所以答案是调用默认浏览器来打开URL。

这时我们可以发现Chrome Custom Tabs的原理:如果Chrome是默认浏览器,那么这个Intent自然就会唤起Chrome,然后Chrome会根据Intent的各个Extra来配置前面所讲的自定义项。这里有一个隐藏的好处:如果你的工作恰好是开发浏览器,那么也可以根据这些Extra信息来定制界面!

三、上手开发

1、首先在你的build.gradle文件中加入dependency

arduino 复制代码
dependencies {
    ...
    implemention 'com.android.support:customtabs:24.1.1'
}

Chrome CustomTab error: java.lang.NoSuchMethodError: No static method startActivity

如果遇到这个问题,需要将版本号改为 25.1.0+ 即可

2、通过 builder 配置自己需要的

java 复制代码
    @OnClick(R.id.customtab)
      public void onClick() {
        String url = "https://www.google.com";
        // 向toolbar添加一个Action Button
        // 'icon'是一张位图(Bitmap),作为action button的图片资源使用

        // 'description'是一个字符串,作为按钮的无障碍描述所使用

        // 'pendingIntent' 是一个PendingIntent,当action button或者菜单项被点击时调用。
        // 在url作为data被添加之后,Chrome 会调用PendingIntent#send()方法。
        // 客户端应用会通过调用Intent#getDataString()获取到URL

        // 'tint'是一个布尔值,定义了Action Button是否应该被着色

        // actionIntent
        Intent actionIntent = new Intent(Intent.ACTION_SEND);
        actionIntent.setType("*/*");
        actionIntent.putExtra(Intent.EXTRA_EMAIL, "example@example.com");
        actionIntent.putExtra(Intent.EXTRA_SUBJECT, "example");
        PendingIntent pi = PendingIntent.getActivity(this, 0, actionIntent, 0);
        Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.button_play);
        //注意在正式项目中不要在UI线程读取图片

        // menuIntent
        Intent menuIntent = new Intent();
        menuIntent.setClass(getApplicationContext(), CustomTabActivity.class);
        PendingIntent pi1 = PendingIntent.getActivity(getApplicationContext(), 0, menuIntent, 0);

        CustomTabsIntent tabsIntent = new CustomTabsIntent.Builder()
            .setToolbarColor(getResources().getColor(R.color.divider_gray)) // 定义 toolbar 的颜色
            .setActionButton(icon, "send email", pi, true) // 添加 action button
            .addMenuItem("menu entry", pi1)  // 添加 menu item
            .setCloseButtonIcon(icon) // 自定义 关闭 按钮
            .build();

        Context context = this;
        if (context instanceof Activity) {
          tabsIntent.launchUrl(this, Uri.parse(url));
        } else {
          Intent intent = tabsIntent.intent;
          intent.setData(Uri.parse(url));
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            context.startActivity(intent, tabsIntent.startAnimationBundle);
          } else {
            context.startActivity(intent);
          }
        }
      }

3、预加载(预启动)

UI的定制是通过使用CustomTabsIntentCustomTabsIntent.Builder类完成的;而速度的提升则是通过使用CustomTabsClient链接Custom Tabs服务,预热Chrome和让Chrome知晓将要打开的URL实现的。

预热Chrome的步骤如下:

4、怎样检测Chrome是否支持Chrome Custom Tabs?

所有支持Chrome Custom Tabs的Chrome浏览器都暴露了一个service。为了检测是否支持Chrome Custom Tabs,可以尝试着绑定service,如果成功的话,那么Customs Tabs可以成功的使用。

5、判断用户手机是否支持 Custom Tabs

建议使用这里面的 CustomTabsHelper.javaCustomTabActivityHelper.java 两个工具类。

参考文章

官方文档

官方源码 qq157755587.github.io/2016/08/12/...

juejin.im/entry/586f0...

欢迎各位关注在下的微信公众号"张氏文画",不光有新鲜的 LeetCode 题解(多种思路,包教包会,开拓思维),还有经典的文章及短视频和大家分享,一起嘿嘿嘿

------乐于分享,共同进步,欢迎留言讨论
------Treat Warnings As Errors
------Any comments greatly appreciated
------Talking is cheap, show me the code
------CSDN:blog.csdn.net/u011489043
------GitHub:github.com/selfconzrr

相关推荐
学代码的小前端1 分钟前
0基础学前端-----CSS DAY9
前端·css
joan_855 分钟前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
m0_7482361136 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_748248941 小时前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_748235611 小时前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink6 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者8 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-8 小时前
验证码机制
前端·后端