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.

Barkermn01
  • 6,781
  • 33
  • 83
Jimmy Canadezo
  • 161
  • 1
  • 10
  • If you temporarily put a copy of the HTML in `assets/` and load it into the `WebView` from there, does it work? – CommonsWare Dec 09 '17 at 21:56
  • `"file:///`. Shouldnt that be `"file://` ? – greenapps Dec 09 '17 at 22:10
  • Tried it. I'm getting the same issue. None of the files are being loaded. @greenapps – Jimmy Canadezo Dec 09 '17 at 22:13
  • There is a `css` folder in assets? – greenapps Dec 09 '17 at 22:14
  • Yes there is. There's CSS, JS, and Images. @greenapes – Jimmy Canadezo Dec 09 '17 at 22:21
  • 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. – twicejr Dec 18 '17 at 10:41

4 Answers4

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.

cytsunny
  • 4,838
  • 15
  • 62
  • 129
0

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", "");
Dhaval Solanki
  • 4,589
  • 1
  • 23
  • 39
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.

Ashish Gupta
  • 737
  • 11
  • 18
  • can u please share you css file too? I m just trying to replace my actual font which is loading through url in webview. I just added my own font in assets and trying to wake my own css like u but i am not succeeded. please help. – Uzair Qaiser Jun 26 '18 at 09:21
  • not working to me, dont know why – famfamfam Mar 09 '22 at 08:08
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>.

Yvonne Aburrow
  • 2,602
  • 1
  • 17
  • 47