Skip to content

Consider replacing WebViewLocalServer with WebViewAssetLoader #483

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
nfischer opened this issue Dec 2, 2019 · 3 comments
Open

Consider replacing WebViewLocalServer with WebViewAssetLoader #483

nfischer opened this issue Dec 2, 2019 · 3 comments

Comments

@nfischer
Copy link

nfischer commented Dec 2, 2019

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).

@jcesarmobile
Copy link
Member

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

@nfischer
Copy link
Author

nfischer commented Dec 4, 2019

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.

@black-hawk85
Copy link

@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.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants