Consider replacing WebViewLocalServer with WebViewAssetLoader
I'm an engineer on the Android WebView team. It recently came to my attention that you're using WebViewLocalServer (probably forked from https://github.com/google/webview-local-server).
Instead of forking this class, we strongly recommend using https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader, which will do most of the heavy lifting for you, and will be maintained as part of our AndroidX library. If this isn't a suitable replacement, we welcome any feedback on our bug tracker.
CC @HazemSamir (the author of WebViewAssetLoader).
Cordova doesn’t support android x yet, so we can’t use android x libraries without forcing users to install a few plugins that make android x possible and that can cause issues with other plugins.
Can the WebViewAssetHandler intercept just “/“? It’s not clear from the docs and fro angular routing and some other frameworks the apps should be served from the root
Yeah, just pass "/" to addPathHandler. This will let you intercept requests to https://some.origin/foo.html or https://some.origin/index.html. However, AssetLoader doesn't do anything special when you load a URL which ends in "/", so https://some.origin/ will not load the index.html file in the corresponding folder. We have a feature request for this at https://issuetracker.google.com/issues/144925597.
@jcesarmobile I have made a small test with WebViewAssetLoader.
Have enabled AndroidX like described here (doesn't seem to make a problem by the way) and implemented the following test code
setContentView(com.getcapacitor.android.R.layout.bridge_layout_main);
webView = findViewById(com.getcapacitor.android.R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setGeolocationEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
// ---- Path handler
// Default path handler not working
// .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
// .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this))
// => implementing custom handler
.addPathHandler("/", new WebViewAssetLoader.PathHandler() {
@Override
public WebResourceResponse handle(String path) {
try {
if (path.isEmpty())
path = "index.html";
InputStream is = getAssets().open("public/" + path);
String mimeType = AssetHelper.guessMimeType(path);
return new WebResourceResponse(mimeType, null, is);
} catch(Exception e) {
}
return null;
}
})
// ----
.build();
webView.setWebViewClient(new WebViewClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
// return super.shouldInterceptRequest(view, request);
return assetLoader.shouldInterceptRequest(request.getUrl());
}
});
// webView.loadUrl("file:///android_asset/public/index.html");
webView.loadUrl("https://appassets.androidplatform.net/");
The App seems to be working. Of course the native part won't work as the plugins aren't bound etc. But maybe you can take this as base.