Android 开发小工具之:Custom Tabs

924 阅读6分钟

H5 做的商城客户端,效果和 android 原生客户端没多大区别,现在 h5 是越来越火了,
android 的小伙伴们又遇到一个新的挑战了。本项目只能学习一下 WebViewActivity 使用,
但是由于 js 看不到,所以补发看到里面的方法,
主要代码:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);
        ButterKnife.bind(this);
        String url = getIntent().getStringExtra(EXTRA_URL);
        mWebView.setWebViewClient(new WebViewClient());
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        mWebView.loadUrl(url);
        setupActionBar(url);
    }

还有就是 CustomTabActivityHelper 类封装了

/**
     * Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView
     *
     * @param activity The host activity
     * @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available
     * @param uri the Uri to be opened
     * @param fallback a CustomTabFallback to be used if Custom Tabs is not available
     */
    public static void openCustomTab(Activity activity,
                                     CustomTabsIntent customTabsIntent,
                                     Uri uri,
                                     CustomTabFallback fallback) {
        String packageName = CustomTabsHelper.getPackageNameToUse(activity);

        //If we cant find a package name, it means there's no browser that supports
        //Chrome Custom Tabs installed. So, we fallback to the webview
        if (packageName == null) {
            if (fallback != null) {
                fallback.openUri(activity, uri);
            }
        } else {
            customTabsIntent.intent.setPackage(packageName);
            customTabsIntent.launchUrl(activity, uri);
        }
    }

    /**
     * Unbinds the Activity from the Custom Tabs Service
     * @param activity the activity that is connected to the service
     */
    public void unbindCustomTabsService(Activity activity) {
        if (mConnection == null) return;
        activity.unbindService(mConnection);
        mClient = null;
        mCustomTabsSession = null;
    }

下面引入正题.

今天来看看其中之一:Custom Tabs. 注意这个指的是 Chrome 浏览器的自定义多窗口的意思而不是指 Android Tab 页。
Chrome 浏览器现在已经成为 Android 原生系统的默认浏览器了。如果在您的应用中需要打开网页内容,之前的做法要么使用 WebView 或者 直接打开第三方浏览器来显示内容。典型的场景比如微信里面的大部分内容都是先在微信自己的 WebView 中显示,然后你可以选择菜单中的在浏览器中打开。而 Chrome 团队认为现在在应用中显示网页内容已经非常常见了,为了方便大家显示网页内容并且保存良好的用户体验,实现了这么一个功能。具体来说,如果您想在应用中打开一个网页,你可以通过 Chrome Custom Tabs 来打开 Chrome 浏览器的一个自定义 Tab 来显示该网页,你可以自定义这个 Tab 的一些属性来保持良好的用户体验,并且让用户感觉这个自定义 Tab 就是您应用的一部分。目前可以自定义如下内容:

  • ActionBar(也就是最上面的 Toolbar,网址一栏)的颜色
  • 自定义 Tab 的进入和退出过场动画 在自定义 Tab 的
  • ActionBar 上添加自定义图标和菜单
  • 自定义返回图标 自定义 Tab 可以通过回调接口来通知应用网页导航的情况
  • 性能更好,使用 Custom Tab 来打开网页的时候,还可以预先加载网页内容,这样当打开的时候,用户感觉非常快。
  • 生命周期管理,使用 Custom tab 可以和您的应用绑定一起,当用户在浏览网页的时候,您的应用也被认为是互动的程序,不会被系统杀死。
  • 可以共享 Chrome 浏览器的 Cookie ,这样用户就不用再登录一遍网站了。 如果用户开启了 Chrome 的数据压缩功能,则一样可以使用
  • 和 Chrome 一样的自动补全功能
  • 每次用的都是最新版本的 Chrome

下图是一个使用 Chrome 、Chrome Custom Tabs 和 WebView 来打开同一个网页速度的对比:

何时选择使用 WebView 和 Chrome Custom Tabs 呢?

如果你之前使用的不是 WebView ,则这种情况都应该用 Chrome Custom Tabs 来打开网页。如果你之前使用的是 WebView,则这里有两种情况来帮组您选择哪种情况更适合你:
如果要显示的网页内容是由您自己控制的,并且网页内容需要和 Android 组件交互,比如通过 JavaScript 接口来调用 Android 系统的一些功能,这种情况下你还需要用 WebView 来实现;其他情况都可以用 Chrome Custom Tabs 来实现。
Chrome Custom Tabs 使用起来非常简单,简单的使用只需要一行代码,和直接调用系统浏览器显示网页没啥区别。通过简单的几项设定,就能让用户感觉浏览第三方网页就像您应用本身的功能一样。
从 Chrome 45 版本开始支持该功能,也是上周刚刚发布,目前仅仅支持 Android 系统。
如何使用?

最简单的使用方式是只需要使用 CustomTabsIntent.Builder 对象来设置一些常用自定义选项,然后调用 CustomTabsIntent.launchUrl(Activity context, Uri url) 函数即可。当然在具体使用过程中,您还需要判断用户手机是否支持 Custom Tabs。建议使用这里面的 CustomTabsHelper.java 和 CustomTabActivityHelper.java 两个工具类。
比如,在 CustomUIActivity.openCustomTab 函数中,通过如下代码即可使用 Custom Tabs 来显示一个网页,并且自定义了 ActionBar 颜色、Activity 转场动画等:

CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder();
// 修改 ActionBar 的颜色
intentBuilder.setToolbarColor(color);
// 添加一个分享按钮
String shareLabel = getString(R.string.label_action_share);
Bitmap icon = BitmapFactory.decodeResource(getResources(),android.R.drawable.ic_menu_share);
PendingIntent pendingIntent = createPendingIntent();
intentBuilder.setActionButton(icon, shareLabel, pendingIntent);
//是否显示网页标题
intentBuilder.setShowTitle(mShowTitleCheckBox.isChecked());
//自定义关闭 Custom tabs 的图标
intentBuilder.setCloseButtonIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_arrow_back));
//自定义 Activity 转场 动画
intentBuilder.setStartAnimations(this, R.anim.slide_in_right, R.anim.slide_out_left);
intentBuilder.setExitAnimations(this, android.R.anim.slide_in_left,android.R.anim.slide_out_right);
// 最后调用助手类 CustomTabActivityHelper 的 openCustomTab 函数来打开一个网址
CustomTabActivityHelper.openCustomTab(this, intentBuilder.build(), Uri.parse(url), new WebviewFallback());

Read more: http://blog.chengyunfeng.com/?p=773#ixzz47Cy4WiEJ

上面的 WebviewFallback 是一个回调接口实现,如果用户手机不支持 Chrome Custom tabs 功能,则调用该接口的 openUri 函数,这里面可以用之前的方式来打开网页,比如用 WebView 或者 用系统第三方浏览器。
另外在 这里 和 这里 还有其他高级用法的示例,可以进一步参考,比如: MainActivity.java 中,可以在 Activity.onStart 中先通过 CustomTabsClient.bindCustomTabsService(Context context, String packageName, CustomTabsServiceConnection connection) 函数来绑定到 CustomTabsService, 绑定成功后,在通过 CustomTabsClient.warmup(long flags) 函数来预加载 Chrome, 这些 Chrome 会加载一些基本控件,这样当打开的时候速度就会比较快;还可以通过 CustomTabsClient.newSession(CustomTabsCallback callback) 函数来获取一个 Custom tabs 的回话,在 Callback 中可以监听该回话的导航操作,比如导航是失败了还是成功了。
可见,只是显示个网页,用 Custom Tabs 还是非常简单的,虽然在国内 Android 手机大部分都用的不是 Chrome 浏览器,还是建议开发者加上该功能,万一遇到几个用户使用了最新版本的 Chrome 浏览器,当他们使用您的应用的时候,是不是会眼前一亮呢?

Read more: blog.chengyunfeng.com/?p=773#ixzz…