一、为什么要用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 来翻开同一个网页速度的比照:

Android开发小工具之:Chrome Custom Tabs

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

假如Web页面是你自己的内容(比如淘宝商品页之于手机淘宝),那么WebView是最好的挑选,因为你或许需求针对网页内容及用户操作做十分多的自界说。假如是跳到一个外部网站,比如在App中点了一个广告链接跳转到广告商的网站,那么主张运用Chrome Custom Tabs。

当然,用户的手机上需求安装Chrome45 或以上版本,而且设为默许浏览器。考虑到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

dependencies {
    ...
    implemention 'com.android.support:customtabs:24.1.1'
}

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

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

2、经过 builder 装备自己需求的

    @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的定制是经过运用CustomTabsIntent和CustomTabsIntent.Builder类完结的;而速度的提高则是经过运用CustomTabsClient链接Custom Tabs服务,预热Chrome和让Chrome知晓即将翻开的URL实现的。

预热Chrome的过程如下:

  • 运用CustomTabsClient#bindCustomTabsService连接service
  • 一旦service连接成功,后台调用CustomTabsClient#warmup发动Chrome
  • 调用CustomTabsClient#newSession创立一个新的session.这个session被用作一切的API恳求
  • 我们能够在创立session时挑选性的增加一个CustomTabsCallback作为参数,这样我们就能知道页面是否被加载完结
  • 经过CustomTabsSession#mayLaunchUrl奉告Chrome用户最有或许加载的页面
  • 调用CustomTabsIntent.Builder结构办法,并传入已经创立好的CustomTabsSession作为参数传入

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

一切支持Chrome Custom Tabs的Chrome浏览器都暴露了一个service。为了检测是否支持Chrome Custom Tabs,能够尝试着绑定service,假如成功的话,那么Customs Tabs能够成功的运用。

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

主张运用这儿面的CustomTabsHelper.java和CustomTabActivityHelper.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