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 來開啟同一個網頁速度的對比:
二、什麼時候用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的步驟如下:
- 使用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 兩個工具類。
——樂於分享,共同進步,歡迎補充
——Any comments greatly appreciated
——誠心歡迎各位交流討論!QQ:1138517609
——CSDN:https://blog.csdn.net/u011489043
——簡書:https://www.jianshu.com/u/4968682d58d1
——GitHub:https://github.com/selfconzrr