Android Webkitまとめ (概要から最新AndroidXまで)

# 1. はじめに

Android Webkitについての概要とAndroid OSと絡めた歴史的な経緯、そして最後にAndroidX Webkitについてまとめています。

# 2. WebkitとWebViewについて

まず、WebkitとWebViewについて概要などを説明します。

## 2.1. WebViewとは？

この記事を読んでいる方には説明不要かと思いますが、WebViewとはAndroidアプリケーションからHTMLやWebページ等のHTMLファイルをレンダリング(表示)する機能を提供してくれるViewのことです。

Android公式サイトのドキュメントは[こちら](https://developer.android.com/reference/android/webkit/WebView)です。

## 2.2. Webkitとは？
サポートライブラリで、WebViewおよびWebブラウジングに関する機能を提供してくれるライブラリのことです。

Android公式サイトのドキュメントは[こちら](https://developer.android.com/reference/android/webkit/package-summary)です。

Android Webkitは、実質WebViewの中核技術であるレンダリングエンジン (ネイティブ側の.soファイルとして存在) をバインディングしたラッパーAPIとなっており、WebViewやブラウザ相当の機能を実現するために必要な機能を提供してくれます。この辺の機能を駆使するとブラウザアプリが作れます。

## 2.3 WebViewレンダリングエンジン

WebViewのレンダリングエンジンは以下に示すように、Android OS 4.4を境に変化しています。

|Android OSバージョン|WebViewレンダリングエンジン|
|:--|:--|
|〜4.3|[WebKit](https://webkit.org)|
|4.4〜現在|[Blink](https://www.chromium.org/blink)|

WebKitとは、主にSafariで利用されているOSSのレンダリングエンジンです。

一方、Blinkとは、ベースは前述のWebKitですが、GoogleがJavaScriptコアをV8エンジンに変更したり、大幅に作り替えたChromeで利用されているレンダリングエンジンです。マイクロソフトがWebKitからBlinkに乗り換えてEdgeブラウザを開発しているなどのことを考えると、Blinkが最も勢力図で勢いがあると考えて良いでしょう。

## 2.3.1 [参考] HTMLレンダリングエンジンの勢力図

世の中の勢力図的には、GoogleのChrome (Blink) 系が勢いがありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/bfc542b4-085c-48e4-59bd-4a3548a64800.png)

なお、ChromeはGoogle製ブラウザですが、OSSのブラウザとしてChromiumというものがあります。Chromiumとは、Googleが開発しているGoogleカスタマイズなしの素のChromeと思ってもらって良いです。GoogleはChromiumというOSSでコア部分を開発し、そこに独自の非公開の味付けをしたものをChromeブラウザとしてリリースしています。

Chromiumについての情報やソースコードなどは[こちら](https://www.chromium.org)を参照してください。

## 2.4. WebViewの歴史的遷移

前述の通り、WebViewのレンダリングエンジンはAndroid 4.4からBlinkに変更になっていますが、それ以外にもWebViewの配布方法やバインディング方法等が歴史的に変わっています。ここを説明します。

WebViewのバインディング先は以下のようにAndroid OSバージョンがUpする度に変更されています。

|Android OSバージョン|WebViewバインディング先|
|:--|:--|
|〜4.4|Android OS組み込み|
|〜6.0|System WebViewから独立し、apkで独立配信されPlayストアで更新になりました。WebViewコアのBlinkはセキュリティ含めて更新頻度が高いため、Android OS組み込みは非現実的のため、このような手段が取られています。|
|7.0〜|ChromeがWebView機能を提供してくれるようになり、Chrome or System WebView（Chrome優先）が開発者メニューで選択可能となりました|
|10|System WebViewのみ。開発者メニューからChrome項目が削除されました|

## 2.5. WebViewの実装メニュー
開発者向けオプションのWebViewの実装からAndroid System WebViewかChromeかを選択できますが、前述の通り、Androi10からはChromeが削除されています。

|<img width="320" height="640" alt="Screenshot_20191223-182545.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/bb2d9078-654d-897d-6523-8621095073ed.png">|
|:-:|

Android10では、System WebViewとChrome WebViewが共通化され、Trichromeと呼ばれる形で提供されるようになっているらしいです。ChromeアプリがWebView機能をSystem WebView側を利用するようになったということでしょうか？
https://chromium.googlesource.com/chromium/src.git/+/master/docs/android_native_libraries.md

# 3. AndroidX Webkit

ここからJetpackの一つである、AndroidX Webkitについて説明します。AndroidX WebkitはSupport Libraryの置き換え以外にも、AndroidX Webkitにのみある新機能があります。しかし、今時点では発展途上でAndroid Webkitの完全な置き換え可能なレベルには到達していません。

AndroidX Webkitの簡易アーキテクチャは以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/56dbd5c7-9be3-ed58-7b02-2c8f5cb3a42b.png)

## 3.1. 新機能

いくつか便利な機能があるため、紹介します。

### 3.1.1. WebViewFeature

APIバージョンコードを気にせず、機能有無でコードを書けます。

#### 従来のコード
```kotlin
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
    WebView.startSafeBrowsing(this.applicationContext) { value ->
        Log.d(TAG, "WebView.startSafeBrowsing: $value")
    }
}
```

#### WebViewFeatureを使ったコード

```kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) {
    WebViewCompat.startSafeBrowsing(this.applicationContext) { value ->
        Log.d(TAG, "WebViewCompat.startSafeBrowsing: $value")
    }
}
```

### 3.1.2. ProxyController

プロキシ設定を簡単に出来ます！

```kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) {
    // proxy1.comが失敗したら、次はproxy2.comのように上から順番に試していく
    val proxyConfig = ProxyConfig.Builder()
        .addProxyRule("proxy1.com")
        .addProxyRule("proxy2.com", ProxyConfig.MATCH_HTTP)
        .addProxyRule("proxy3.com", ProxyConfig.MATCH_HTTPS)
        .addBypassRule("www.google.*") // プロキシ設定除外のホスト
        .build()

    // Executor
    val executor = Executor { Log.d(TAG, "${Thread.currentThread().name} : executor") }

    // プロキシ設定変更が受付された時に呼ばれる？呼ばれないような…
    val listener = Runnable { Log.d(TAG, "${Thread.currentThread().name} : listener") }

    // WebViewのプロキシ設定をシステム設定から上書き
    ProxyController.getInstance().setProxyOverride(proxyConfig, executor, listener)

    // システムの設定に戻す
    ProxyController.getInstance().clearProxyOverride(executor, listener)
}
```

### 3.1.3. ダークモード設定　※webkit:1.2.0からの機能

WebViewのダークモードの設定が可能です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/636a7938-e189-d1c5-114c-da784c95c2e1.png)

```kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
   //WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_AUTO)
    //WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_OFF)
    WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
}
```

## 3.2 使い始めるために

```Build.gradle
dependencies {
    implementation “androidx.webkit:webkit:1.2.0”
}
```

## 3.3 サンプルコード
[github](https://github.com/Kurun-pan/androidx-webkit-sample/blob/master/app/src/main/java/com/example/webkit/MainActivity.kt)に、まずはそのまま動かすレベルのサンプルコードを用意していますので、必要であればご利用下さい。

# 4. 参考文献

* [AndroidX WebKitプロジェクト](https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-work-release/webkit/README.md)
* [androidx.webkit公式サイト](https://developer.android.com/reference/androidx/webkit/package-summary)