Due to browser engine limitations, both of the 3D WebView packages for Android have limitations with loading web pages from StreamingAssets when the "Split Application Binary" option is enabled in "Android Player Settings" -> "Publishing Settings".
3D WebView for Android is powered by the Android System WebView, which doesn't support loading web pages from StreamingAssets when "Split Application Binary" is enabled.
3D WebView for Android with Gecko Engine can load web pages from StreamingAssets with "Split Application Binary" enabled, however the Gecko browser engine fails to load 3D WebView's built-in browser extension in that scenario, which breaks some of 3D WebView's features. For example, some APIs such as IWebView.ExecuteJavaScript() and message passing don't function correctly.
If you encounter these limitations, here are options to resolve it:
The first option is to disable "Split Application Binary".
Another option is to copy the assets to a different location (such as Application.temporaryCachePath) and then load them via a file:// URL like described here. Here's an example:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Networking;
using Vuplex.WebView;
/// <summary>
/// On Android, copies web files from StreamingAssets to a temporary cache path for loading in a webview.
/// https://support.vuplex.com/articles/android-split-binary-streaming-assets
/// </summary>
class CopyFilesFromStreamingAssetsToDiskAndLoad : MonoBehaviour {
// TODO: Set these fields via the Editor's inspector tab.
[Tooltip("The relative path within the StreamingAssets folder of the main HTML file to load. For example, if the main HTML file is located at StreamingAssets/index.html, then set this to "index.html".")]
public string htmlFileRelativePathWithinStreamingAssets;
[Tooltip("The WebViewPrefab or CanvasWebViewPrefab to load the files in.")]
public BaseWebViewPrefab webViewPrefab;
[Tooltip("(optional) Relative paths within the StreamingAssets folder of additional files to copy. This can be used to copy additional resources that the main HTML file loads, such as CSS and JS files. For example, if a CSS file is located at StreamingAssets/css/styles.css, then add that file to this list as "css/styles.css".")]
public string[] relativePathsOfOtherFilesToCopy;
TaskCompletionSource<bool> _copyFilesTaskSource = new TaskCompletionSource<bool>();
async void Start() {
Assert.IsTrue(!String.IsNullOrEmpty(htmlFileRelativePathWithinStreamingAssets), "The fileName field on the LoadFileFromCachePath script hasn't been set. Please set it via the Editor inspector tab.");
Assert.IsNotNull(webViewPrefab, "The webViewPrefab field on the LoadFileFromCachePath script hasn't been set. Please set it via the Editor inspector tab.");
webViewPrefab.InitialUrl = null;
#if UNITY_ANDROID && !UNITY_EDITOR
// On Android, copy the files from StreamingAssets to Application.temporaryCachePath and load from there.
StartCoroutine(_copyFiles());
await _copyFilesTaskSource.Task;
await webViewPrefab.WaitUntilInitialized();
var fileUrl = "file://" + Path.Combine(Application.temporaryCachePath, htmlFileRelativePathWithinStreamingAssets);
webViewPrefab.WebView.LoadUrl(fileUrl);
#else
// In the editor and on non-Android platforms, load the file from StreamingAssets without copying.
await webViewPrefab.WaitUntilInitialized();
var fileUrl = "file://" + Path.Combine(Application.streamingAssetsPath, htmlFileRelativePathWithinStreamingAssets);
webViewPrefab.WebView.LoadUrl(fileUrl);
#endif
}
IEnumerator _copyFiles() {
var relativeFilePaths = new List<string> { htmlFileRelativePathWithinStreamingAssets };
if (relativePathsOfOtherFilesToCopy != null) {
relativeFilePaths.AddRange(relativePathsOfOtherFilesToCopy);
}
foreach (var relativeFilePath in relativeFilePaths) {
var streamingAssetsFilePath = Path.Combine(Application.streamingAssetsPath, relativeFilePath);
// On Android, StreamingAssets are compressed inside the APK, so they can't be accessed via
// C# file APIs and must instead be accessed via UnityWebRequest:
// https://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html
using (UnityWebRequest webRequest = UnityWebRequest.Get(streamingAssetsFilePath)) {
yield return webRequest.SendWebRequest();
if (webRequest.result == UnityWebRequest.Result.Success) {
var text = webRequest.downloadHandler.text;
var temporaryCacheFilePath = Path.Combine(Application.temporaryCachePath, relativeFilePath);
if (relativeFilePath.Contains("/") || relativeFilePath.Contains("\")) {
var directoryPath = Path.GetDirectoryName(temporaryCacheFilePath);
Directory.CreateDirectory(directoryPath);
}
File.WriteAllText(temporaryCacheFilePath, webRequest.downloadHandler.text);
} else {
Debug.LogError($"UnityWebRequest was unsuccessful for file {relativeFilePath}: {webRequest.result}");
}
}
}
_copyFilesTaskSource.SetResult(true);
}
}