blob: 485a81743994120f8701c594428c7549b1120048 [file] [log] [blame] [view]
pasko50653f22015-10-16 12:01:491# Using Custom Tabs
2
3## Summary
4
5This presents a few example applications using Custom Tabs, and a possible usage
6of the APIs, both intent-based and the the background service. It covers UI
7customization, setting up callbacks, pre-warming, pre-fetching, and lifecycle
8management. Here we assume that Chrome's implementation of Custom Tabs is used.
9Note that this feature is in no way specific to Chrome, but slight differences
10may exist with other implementations.
11
12### Overview
13
14In particular, this covers:
15
16* UI customization:
17 * Toolbar color
18 * Action button
19 * Custom menu items
20 * Custom in/out animations
21* Navigation awareness: the browser delivers callbacks to the application for
22 navigations in the Custom Tab.
23* Performance optimizations:
24 * Pre-warming of the Browser in the background, without stealing resources
25 from the application
26 * Providing a likely URL in advance to the browser, which may perform
27 speculative work, speeding up page load time.
28
29These features are enabled through two mechanisms:
30
31* Adding extras to the `ACTION_VIEW` intent sent to the browser.
32* Connecting to a bound service in the target browser.
33
34### Code Organization
35
36To get full benefits of the Custom Tabs APIs, it is recommended to use the
37[Android Support Library](https://developer.android.com/tools/support-library/index.html).
38
39The code in this repository is organised in four parts:
40
41* `demos/`: This module contains sample implementations for Chrome Custom Tabs using the Android
42 Support Library. Feel free to re-use the classes withing this module.
43* `shared/`: Shared code between the `Application` and `demos` modules. Feel free to
44 re-use the classes within this directory, which are only provided as a convenience.
45 In particular,`CustomTabsHelper` can be re-used. This code is not required to use Custom Tabs.
46* `customtabs/`: Code within this directory is in the package
47 `android.support.customtabs`. This contains code analog to the Android Support library, but with
48 the latest version of Chrome Custom Tabs, enabling features that may still not be available on
49 the Android Support Library. API is subject to changes and this code should only be used if you
50 want to test the latest features. It is recommended to copy the code as-is to your project and
51 remove the Android Support Library for Chrome Custom Tabs from the `build.gradle` file.
52* `Application/`: Example application code, in the package
53 `org.chromium.customtabsclient`. This code uses the latest version of the Chrome Custom Tabs,
54 contained in the module `customtabs`.
55
56## UI Customization
57
58UI customization is done through the methods exposed by
59`CustomTabsIntent.Builder`.
60
61**Example:**
62```java
63CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
64builder.setSession(session);
65builder.setToolbarColor(Color.BLUE);
66// Application exit animation, Chrome enter animation.
67builder.setStartAnimations(this, R.anim.slide_in_right, R.anim.slide_out_left);
68// vice versa
69builder.setExitAnimations(this, R.anim.slide_in_left, R.anim.slide_out_right);
70
71CustomTabsIntent customTabsIntent = builder.build();
72customTabsIntent.launchUrl(this, packageName, url);
73```
74
75In this example, no UI customization is done, aside from the animations and the
76toolbar color. The general usage is:
77
781. Create an instance of `CustomTabsIntent.Builder`
792. Build the UI using the methods of `CustomTabsIntent.Builder`
803. Call `CustomTabsIntent.Builder.build()`
814. Call `CustomTabsIntent.launchUrl()`
82
83The communication between the custom tab activity and the application is done
84via pending intents. For each interaction leading back to the application (menu
85items and action button), a
86[`PendingIntent`](http://developer.android.com/reference/android/app/PendingIntent.html)
87must be provided, and will be delivered upon activation of the corresponding UI
88element.
89
90## Navigation
91
92The hosting application can elect to get notifications about navigations in a
93Custom Tab. This is done using a callback extending
94`android.support.customtabs.CustomTabsCallback`, that is:
95
96```java
97void onNavigationEvent(int navigationEvent, Bundle extras);
98```
99
100This callback is set when a `CustomTabsSession` object is created, through
101`CustomTabsSession.newSession()`. It thus has to be set:
102
103* After binding to the background service
104* Before launching a URL in a custom tab
105
106The two events are analogous to `WebViewClient.onPageStarted()` and
107`WebViewClient.onPageFinished()`, respectively (see
108[WebViewClient](http://developer.android.com/reference/android/webkit/WebViewClient.html)).
109
110## Optimization
111
112**WARNING:** The browser treats the calls described in this section only as
113 advice. Actual behavior may depend on connectivity, available memory and other
114 resources.
115
116The application can communicate its intention to the browser, that is:
117* Warming up the browser
118* Indicating a likely navigation to a given URL
119
120In both cases, communication with the browser is done through a bound background
121service. This binding is done by
122`CustomTabClient.bindCustomTabsService()`. After the service is connected, the
123client has access to a `CustomTabsClient` object, valid until the service gets
124disconnected. This client can be used in these two cases:
125
126* **Warmup**: Warms up the browser to make navigation faster. This is expected
127 to create some CPU and IO activity, and to have a duration comparable to a
128 normal Chrome startup. Once started, Chrome will not use additional
129 resources. This is triggered by `CustomTabsClient.warmup()`.
130* **Hint about a likely future navigation:** Indicates that a given URL may be
131 loaded in the future. Chrome may perform speculative work to speed up page
132 load time. The application must call `CustomTabsClient.warmup()` first. This
133 is triggered by `CustomTabsSession.mayLaunchUrl()`.
134
135**Example:**
136```java
137// Binds to the service.
138CustomTabsClient.bindCustomTabsService(context, packageName, new CustomTabsServiceConnection() {
139 @Override
140 public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
141 // mClient is now valid.
142 mClient = client;
143 }
144
145 @Override
146 public void onServiceDisconnected(ComponentName name) {
147 // mClient is no longer valid. This also invalidates sessions.
148 mClient = null;
149 }
150});
151
152// With a valid mClient.
153mClient.warmup(0);
154
155// With a valid mClient.
156CustomTabsSession session = mClient.newSession(new CustomTabsCallback());
157session.mayLaunchUrl(Uri.parse("https://www.google.com"), null, null);
158
159// Shows the Custom Tab
160builder.build().launchUrl(context, packageName, Uri.parse("https://www.google.com"));
161```
162
163**Tips**
164
165* If possible, issue the `warmup` call in advance to reduce waiting when the
166 custom tab activity is started.
167* If possible, advise Chrome about the likely target URL in advance, as the
168 loading optimization can take time (requiring network traffic, for instance).