ReactNativeのWebViewからAsset Pack のアセットを使う

TL;DR

  • とあるReactNative (!=expo) アプリのインストールサイズが150MBを超えてしまったので、急遽 Asset Packを使う羽目になった。
  •  deliveryType = "install-time" を適用して分割はできたものの、WebViewから参照するにはどうするんだ?ってなった 。
  •  WebView から参照する目的では 何もしなくてよかった

 

webViewAssetsをベースAPKから分離する・・為にAsset Packを準備する

このアプリでは元々対象ファイルを /webViewAssets/assets/ に配置して /android/app/build.gradle から以下で参照させていました。

android {
  :
  sourceSets {
    main {
      assets.srcDirs = [ "../../webViewAssets/assets" ]
    }
  }
}

 

ネイティブまたは Java 向けのビルド  |  Android デベロッパー  |  Android Developers

に従って /android/webview_assets/src/main/assets/ ディレクトリ (ここに対象ファイルをコピーする) や /android/webview_assets/build.gradle , /android/app/build.gradle を記述します。 

対象ファイルのコピー処理は、gradle でも出来る筈ですが、このアプリは gradle を呼び出すシェルスクリプトがあるのでそこでやりました。要調査です。

 

WebViewから参照する

このアプリでは  WebView#source = { uri: 'file:///android_asset/index.html' } としてアセットにアクセスしていました。このまま動きます。

 

ローカルでAABの動作確認をする

アセット配信をテストする  |  Android デベロッパー  |  Android Developers

の記事に従うと、ビルドした AAB を元にAKPSを生成してローカルインストールできます。
生成したAPKSをunzipすると asset-slices/webview_assets-master.apk なるものがあることも判ります。

 

Play Store の App Bundle エクスプローラーで眺める

内部テストリリースの準備などで Play Store にAABをアップロードすると、App Bundle エクスプローラーの「配信」タブで「機能モジュール」とは別に「Asset packs」に「webview_assets」があることを確認できます。

 

通常のAPKビルドや開発時実行(react-native run-android)と棲み分ける

AABにしたくない状態では Asset Pack 部分は動作しない訳ですが、このアプリでは環境変数で gradle の動作を切り替えることにしました。

export ORG_GRADLE_PROJECT_USE_ASSET_PACK=t

でAsset Packを有効にする事にして、こんな感じ。
/android/app/build.gradle

android {
  :
  sourceSets {
    main {
      if (project.hasProperty('USE_ASSET_PACK')) {
        assets.srcDirs = ["../../webViewAssets/assets"]
      }
    }
  }

  if (project.hasProperty('USE_ASSET_PACK')) {
    assetPacks = [":webview_assets"]
  }
}