This presents an example application using Chrome Custom Tabs, and a possible usage of both the intent and the background service APIs. It covers UI customization, callback setup, pre-warming and pre-fetching, and lifecycle management.
Chrome Custom Tabs provides a way for an application to customize and interact
with a Chrome Activity
on Android, to make it a part of the application
experience, while retaining the full functionality and performance of a complete
web browser.
In particular, this covers:
- UI customization:
- Toolbar color
- Action button
- Custom menu items
- Custom in/out animations
- Navigation awareness: the browser delivers a callback to the application upon an external navigation.
- Performance optimizations:
- Pre-warming of the Browser in the background, while avoiding stealing resources from the application
- Providing a likely URL in advance to the browser, which may perform speculative work, speeding up page load time.
These features can be accessed by appending extras to the ACTION_VIEW
intent
and connecting to a bound service in Chrome. Here we present the way this is
handled in the example client application. Feel free to re-use the provided
classes in this sample, namely:
CustomTabUiBuilder
: Builds the intent extras used to customize the Custom Tab UI.CustomTabActivityManager
: Handles the connection with the background service, the load time optimizations and the "KeepAlive" service.KeepAliveService
: Empty remote service used by Chrome to keep the application alive.
UI customization is handled by the CustomTabUiBuilder
class. An instance of this
class has to be provided to CustomTabActivityManager.loadUrl()
to load a URL in a
custom tab.
Example:
CustomTabUiBuilder uiBuilder = new CustomTabUiBuilder().setToolbarColor(Color.BLUE);
// Application exit animation, Chrome enter animation.
uiBuilder.setStartAnimations(this, R.anim.slide_in_right, R.anim.slide_out_left);
// vice versa
uiBuilder.setExitAnimations(this, R.anim.slide_in_left, R.anim.slide_out_right);
customTabManager.loadUrl(url, uiBuilder);
In this example, no UI customization is done, aside from the animations and the toolbar color. The general usage is:
- Create an instance of
CustomTabUiBuilder
- Build the UI using the methods of
CustomTabUiBuilder
- Provide this instance to
CustomTabActivityManager.loadUrl()
The communication between the custom tab activity and the application is done
via pending intents. For each interaction leading back to the application
(through menu items), a
PendingIntent
must be provided, and will be delivered upon activation of the UI element.
After a URL has been loaded inside a custom tab activity, the application can
receive a notification when the user navigates to another location. This is done
using a callback. The callback implements the interface of
CustomTabActivityManager.NavigationCallback
, that is:
void onUserNavigationStarted(String url, Bundle extras);
void onUserNavigationFinished(String url, Bundle extras);
This callback must be set before binding to the service, that is:
- Before calling
CustomTabActivityManager.bindService()
- Before calling
CustomTabActivityManager.loadUrl()
It can only be set once.
WARNING: The browser treats the calls described in this section only as advice. Actual behavior may depend on connectivity, available memory and other resources.
The application can communicate its intention to the browser, that is:
- Warming up the browser
- Indicating a likely navigation to a given URL
In both cases, communication with the browser is done through a bound background
service. This binding is done by CustomTabActivityManager.bindService()
. This
must be called before the other methods discussed in this section.
- Warmup: Warms up the browser to make navigation faster. This is expected
to create some CPU and IO activity, and to have a duration comparable to a
normal Chrome startup. Once started, Chrome will not use additional
resources. To warm up Chrome, use
CustomTabActivityManager.warmup()
. - May Launch URL: Indicates that a given URL may be loaded in the
future. Chrome may perform speculative work to speed up page load time. The
application must call
CustomTabActivityManager.warmup()
first.
Example:
// It is preferable to call this once the main activity has been shown.
// These calls are non-blocking and can be issued from the UI thread
// or any other thread. However, CustomTabActivityManager is not threadsafe.
CustomTabActivityManager customTabManager = CustomTabActivityManager.getInstance(activity);
customTabManager.bindService();
customTabManager.warmup();
// This URL is likely to be loaded. Tell the browser about it.
customTabManager.mayLaunchUrl(url, null);
// Show the custom tab.
customTabManager.loadUrl(url, uiBuilder);
Tips
- If possible, issue the warmup call in advance to reduce waiting when the custom tab activity is started.
- If possible, advise Chrome about the likely target URL in advance, as the loading optimization can take time (requiring network traffic, for instance).
Bugs
Issues and bugs related to these examples and the Chrome implementation of Custom Tabs are tracked in the Chromium Issue Tracker. This template will notify relevant people faster than issues on GitHub, this is the preferred way to report.