Android のアプリ内ブラウザについてのまとめ

## はじめに

Android のアプリ内ブラウザについて、どのような種類があり、それぞれにどんな特徴やメリット・デメリットがあるのかについてまとめます。この記事を読むと、次のことが理解できるかもしれません。

- Android の普段使っているアプリで Web ページを開く時に裏でどのような技術が使われているか
- Web ページをアプリ内で開く機能を実装するとき、目的に沿ったアプリ内ブラウザを選択できるようになる
- 実際に運用されている著名なアプリのアプリ内ブラウザはどうなっているか

## Android のアプリ内ブラウザについて

Android のアプリ内ブラウザについて、3パターンの実装をご紹介します。

### 特に実装を行わない場合

リンクをタップすると、OS のデフォルトとして設定されたブラウザで Web ページを開きます。この挙動は、スマホアプリ内でリンクをタップした際の処理が特に書かれていない場合のものになります。

#### メリット

ユーザが普段使っているブラウザで Web ページを開くことができるので、普段通りのブラウジングを行うことができます。また、当然クッキーやセッションもブラウザ内に保持されているので、リンクを開く度にログイン状態が初期化されるということはありません。

#### デメリット

スマホアプリからリンクをタップした際、ブラウザアプリが立ち上がってしまうので、元のスマホアプリからは離脱してしまいます。そのため、Web ページを見た後に再びスマホアプリに戻りたい際は、ユーザ自らがアプリの切り替えを行う必要があります。これはユーザ体験としてもあまりよろしくない上に、アプリ側でユーザがブラウザ内で何をしているかトラッキングすることができません。

### WebView を使った実装

次に [**WebView**](https://developer.chrome.com/multidevice/webview/overview) と呼ばれる、アプリ内で Web ページの取得・表示を行うことができる機能を使った実装について紹介します。

#### メリット

WebView を使うことで、リンクをタップした際に別なブラウザを立ち上げることなくアプリ内で Web ページを表示することが可能になります。そのため、ユーザが Web ページを見る際にブラウザアプリに遷移する必要がなくなり、1つのアプリ内で操作を完結させることができます。

また、開発者の目線としてもいくつかメリットがあります。WebView では、通常のブラウザでは不可能な以下のような処理も記述することが可能です。

- アクセス可能なドメインの制限を設ける
- クッキーに保存されたデータを取り出しアプリ側に受け渡す
- 特定のリンクに対してアプリ側でパラメータを付与する
- アプリ側のストレージでセッションを永続化する

#### デメリット

WebView はアプリ内で実装されるため、普段使っているブラウザからは完全に独立しています。そのため、過去にログインしたことがあるサイトは再ログインが必要になりますし、ブックマークや履歴を使用するといったことも不可能になります。その他にも次のようなデメリットがあると考えられます。

- WebView でどんな機能を使えるかは開発者次第
- セキュリティポリシー（サードパーティクッキーやクロスオリジンの制約など）も開発者次第になる
- WebView を使用するユーザ or サードパーティの開発者は、その WebView にどんな機能があるのかが分かりづらい（使ってみないとわからない）

### Chrome Custom View を使った実装

ここでは、アプリ内ブラウザを簡単に実装できる [**Chrome Custom Tabs**](https://developer.chrome.com/multidevice/android/customtabs) について説明します。

#### メリット

Chrome Custome Tabs は Chrome のプロセスで動く WebView を提供してくれます。そのため、動作は Chrome とほぼ同じものとなる上に、Pre-warming という機能でバックグラウンドで常に Chrome のプロセスが待機しているので、WebView よりも高速に動作するという特徴があります。他にも以下のメリットが挙げられます。

- シンプルに実装することができる
- メニューやツールバー、アクションボタンなどの UI パーツをある程度自由に構築できる
- セキュリティポリシーやブラウザの基本機能は Chrome と同一のもの
- Chrome アプリ内のクッキーやセッションを Chrome Custom Tabs に引き継いでくれるので、ログイン状態を保持できる

#### デメリット

一方でデメリットもあります。Chrome Custom Tabs の実装で手を加えることができるのは、ほぼ UI 部分のみとなります。例えば WebView で実装することができたアクセス制限やクッキーの制御などは実装することができません。そのため、アプリ側で細かい処理を行いたい場合は Chrome Custom Tabs はあまり向いていないと言えるでしょう。

## WebView vs Chrome Custome Tabs

WebView が推奨されるのは、アプリ内からアクセスするサイトが「**自身のサービスサイトもしくはそれに関連するサイトのみ**」を想定する場合です。たとえば商品検索ボタンをアプリに組み込んで、そのボタンを押してウェブサイトにある商品一覧画面を表示するような実装を行うとします。その際に、WebView で実装を行うと、商品一覧画面以外のページへのアクセスを WebView 上で制限することができたり、商品一覧画面から無関係のページへのリンクを削除する、といったことが可能です。

一方、Chrome Custom Tabs の利用が推奨されるのは「**不特定のサイトにアクセスする可能性がある**」場合です。アプリ内に様々なサイトへのリンクが表示されるような場合、それに対して開発者がアプリ内ブラウザのセキュリティポリシーを設定したり、悪意あるサイトの表示を制限する、といった処理を実装するのはコストがかかります。Chrome Custome Tabs を使うことでブラウザに求められる基本的なセキュリティや機能は全て Chrome が提供してくれるため、開発者はアプリの実装に集中することができます。

以下のページに詳細が書かれておりますので、興味のある方は読んでいただければと思います。
[Google Chrome Developer - Chrome Custome Tabs](https://developer.chrome.com/multidevice/android/customtabs#whentouse)

## 有名サービスのアプリ内ブラウザの例

実際に有名サービスのアプリ内ブラウザがどのように実装されているか見てみましょう。
今回は独断と偏見のもと、 `Twitter`, `Facebook` の Android アプリに着目してみました。

### 検証環境

今回検証を行った際の環境は以下の通りです。

- Android 端末: シミュレータを使用 ( Android 5.1 )
- シミュレータ: [GenyMotion](https://www.genymotion.com/)
- ADB: [Chrome ADB](https://chrome.google.com/webstore/detail/adb/dpngiggdglpdnjdoaefidgiigpemgage)

検証環境の構築はこちらの記事を参考にしました。ありがとうございました！
[Qiita - Genymotion & Google Chrome + ADB を用いた、Android Webデバッグ環境の構築（実機不要）](http://qiita.com/pm11/items/99815e76b3e07eaee3d5)

### Twitter

Android の Twitter アプリでは **Chrome Custom Tabs** が使用されています。
実際に、Twitter アプリでリンクを開くと以下のような画面に遷移します。

<img width="500" alt="スクリーンショット 2016-10-14 14.36.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/61564/37055217-9f15-8ae2-185d-15ec88a497dc.png" width="400">

画像のメニューの中に、`Powered by Chrome` と書かれているのが分かるでしょうか。Chrome Custom Tabs ではメニュー UI の変更は開発者がある程度自由に行えるため、Twitter 独自の `ツイートで共有する` や `ダイレクトメッセージで共有する` といったオリジナルのメニューが表示されています。

Chrome ADB のインスペクタを使って見てみると、下の画像のように Chrome のプロセスが立ち上がっていることがわかります。
Chrome Custom Tabs の Pre-warming の機能により、一度ページを閉じた後も Chrome のプロセスは残り続けて、リンクがタップされるのを待ち続けます。

<img width="628" alt="スクリーンショット 2016-10-14 14.37.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/61564/5377f358-2cad-da9a-55c4-840a53952354.png" >

### Facebook

一方、Facebook アプリでは **WebView** が使用されています。
Facebook でリンクをタップすると、次のような画面が表示されます。

<img width="500" alt="dsfasdfasdfasdf.png" src="https://qiita-image-store.s3.amazonaws.com/0/4823/5932c736-4198-419b-c2aa-c04326ed2c2b.png">

Facebook は Twitter と異なり、オリジナルのシェアボタンをメニューの隣に表示させています。
インスペクタで覗くと、以下のように WebView のプロセスが立ち上がっていることが分かります。

<img width="632" alt="スクリーンショット 2016-10-14 14.45.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/61564/14b10c69-af07-23ca-1a17-0c75c102d2fa.png">

## まとめ

Android のアプリ内ブラウザの種類と特徴について述べ、実際に有名アプリでは何が使われているかについて調査しました。
今後 Android のアプリ内ブラウザを実装する上では、用途や目的に応じて最適な方法を選択することが重要と言えるでしょう。
iOS についても似たような実装が行えるそうなので、ぜひ調べてみたいと思います。
何か気になるところ、間違いなどございましたらお気軽にコメントをいただければと思います。