3

I've been searching for hours for a solution; and although there are similar situations, mine I think is a bit different. I have a website that I'm loading into webview

    setContentView(R.layout.activity_main);
    WebView myWebView = (WebView) findViewById(webview);
    myWebView.loadUrl("http://my-website.com/index.php");
    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);

    myWebView.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.toString());
            return true;
        }
    }); }

It's loading the website fine. No issues. What I'm trying to do (because there are alot of CSS & JS files) is load these files from the assets folder of the Android App - I'm trying to make the page load faster.

<link href="file:///android_asset/css/keyframes.css" rel="stylesheet" type="text/css">
<link href="file:///android_asset/css/materialize.min.css" rel="stylesheet" type="text/css">
<link href="file:///android_asset/css/swiper.css" rel="stylesheet" type="text/css">
<link href="file:///android_asset/css/swipebox.min.css" rel="stylesheet" type="text/css">
<link href="file:///android_asset/css/style.css" rel="stylesheet" type="text/css">

It is currently not loading any of my CSS files which are called this way. I really don't mean to pester anybody with a simple problem, It's just been bothering me and I'm not good with Java. Also, this is NOT a local HTML page. This is a PHP page loaded from a remote server.

6
  • If you temporarily put a copy of the HTML in assets/ and load it into the WebView from there, does it work? Commented Dec 9, 2017 at 21:56
  • "file:///. Shouldnt that be "file:// ? Commented Dec 9, 2017 at 22:10
  • Tried it. I'm getting the same issue. None of the files are being loaded. @greenapps Commented Dec 9, 2017 at 22:13
  • There is a css folder in assets? Commented Dec 9, 2017 at 22:14
  • 1
    If you want true performance, cache the output and place the output at the exact requested location. With a rewrite to index.php on a non-existing file the compilation is done once, to then write the output to e.g. /assets/asdugh3e9adHASH.css ( /assets/asdugh3e9adHASH.css > index.php?path=$1) The unique identifier must be determined by gathering the file modified times / filenames and hashing that. This way PHP is not even executed on load of existing asset sets. Commented Dec 18, 2017 at 10:41

4 Answers 4

1

I am not a mobile developer, but I am a web developer that did write some webview pages for my mobile developer colleagues.

As far as I know, you are not able to access file system in webview. However, you can let your app cache the css / js files.

viewer.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT)

(This is from an answer here on stackoverflow) (and here is the document on cache settings)

By using the default cache settings, the CSS / JS files will be cached after downloaded in the first time, as it was cached in normal browser. So you can simply use

<link href="https://your.domain/css/style.css" rel="stylesheet" type="text/css">

to achieve the faster page load you want.

Sign up to request clarification or add additional context in comments.

Comments

1

If you want to load css and js from local asset folder then first you need to download your webpage and then after you need to pass in web browser like following way,

Download Data Like using this :

public String getHtmlContent(String urlToLoad) {
        String outputStr = "";
        BufferedReader inputString = null;
        try {
            URL urlLoad = new URL(urlToLoad);
            inputString = new BufferedReader(new InputStreamReader(urlLoad.openStream()));
            String str;
            while ((str = inputString.readLine()) != null) {
                outputStr += str;
            }
        } catch (MalformedURLException e) {
        } catch (IOException e) {
        } finally {
            if (inputString != null) {
                try {
                    inputString.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return outputStr;
    }

Then after you need to put your js and css file inside of asset folder and then need to define a url in web page like following

<script src="file:///android_asset/jquery.min.js" type="text/javascript"></script>

You need set all the url using like file:///android_asset/ then after your css or js name,

After all thing finish you need to set your webpage content with webview like following

String webData = getHtmlContent("http://webisteaddress.com/index.html");
    mWebView.loadDataWithBaseURL("file:///android_asset/", webData, "text/html", "utf-8", "");

Comments

0

Use this function to load CSS & JavaScript inside your WebView: inject both CSS & JavaScript inside onCreate() on WebViewClient:

     webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url)
        {
            injectJavaScript(view);
            injectCSS();

         }

Create two methods to inject JavaScript & CSS(from res/raw):

    private boolean injectJavaScript(WebView view){
        view.loadUrl("javascript:(function() { " +
            "var head = document.getElementsByTagName('header')[0];"
            + "head.parentNode.removeChild(head);" + "console.log('true');"+
            "})()");
        view.loadUrl("javascript:(function() { " +
            "var footer = document.getElementsByTagName('footer')[0];"
            + "footer.parentNode.removeChild(footer);" +
            "})()");
        view.loadUrl("javascript:(function() { " +
            "var nav = document.getElementsByTagName('nav')[0];"
            + "nav.parentNode.removeChild(nav);" +
            "})()");
        view.loadUrl("javascript:(function() { " +
            "var set = document.getElementsByClassName('banner');"
            + "set[0].style.margin = '0px';" +
            "})()");
    return true;
    }
    private void injectCSS() {
    try {
        InputStream inputStream = getResources().openRawResource(R.raw.css);
        byte[] buffer = new byte[inputStream.available()];
        inputStream.read(buffer);
        inputStream.close();
        String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
        wv1.loadUrl("javascript:(function() {" +
                "var parent = document.getElementsByTagName('head').item(0);" +
                "var style = document.createElement('style');" +
                "style.type = 'text/css';" +
                "style.innerHTML = window.atob('" + encoded + "');" +
                "parent.appendChild(style)" +
                "})()");

    } catch (Exception e) {
        e.printStackTrace();
    }
}

This worked for me like a charm.

Comments

0

Loading CSS using <link rel="stylesheet" href=""/> is going to be deprecated in March 2018. I just got a warning message for this in Developer Console today.

This is because nothing renders on the page till all the CSS has loaded.

So instead, the suggestion is that we load the CSS using JavaScript, and have a small inline stylesheet to render the basic look of the page; plus separate stylesheets for each section of the page, which are called from the <body> rather than the <head>.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.