Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Consider replacing WebViewLocalServer with WebViewAssetLoader #483

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.

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

No branches or pull requests

3 participants