1. 程式人生 > >Android開發小工具之:Chrome Custom Tabs

Android開發小工具之:Chrome Custom Tabs

參考文章

官方文件

官方原始碼

http://qq157755587.github.io/2016/08/12/custom-tabs-best-practices/

https://juejin.im/entry/586f089c61ff4b006d29f9c0

一、為什麼要用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 來開啟同一個網頁速度的對比:

custom-tabs-vs-chrome-vs-webview.gif

二、什麼時候用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

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, "[email protected]");
    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的步驟如下:

4、怎樣檢測Chrome是否支援Chrome Custom Tabs?

所有支援Chrome Custom Tabs的Chrome瀏覽器都暴露了一個service。為了檢測是否支援Chrome Custom Tabs,可以嘗試著繫結service,如果成功的話,那麼Customs Tabs可以成功的使用。

5、判斷使用者手機是否支援 Custom Tabs

建議使用這裡面的 CustomTabsHelper.javaCustomTabActivityHelper.java 兩個工具類。

——樂於分享,共同進步,歡迎補充
——Any comments greatly appreciated
——誠心歡迎各位交流討論!QQ:1138517609
——CSDN:https://blog.csdn.net/u011489043
——簡書:https://www.jianshu.com/u/4968682d58d1
——GitHub:https://github.com/selfconzrr