9

I'm trying to read a local javascript file (jQuery) stored in assets from an Android webview. I do not want to load-with-base-url since my images and html are served remotely.

To Summarize : - Load local jQuery (in assets folder) into a remotely loaded page in Android webview.

After long hours of browsing going in vain, I decided to put up this question here. Please help.

Thanks!

3 Answers 3

10
  1. Define a Javascript Interface like the one below that will read your jquery file from assets directory

    class JavaScriptInterface {
    
        @JavascriptInterface
        public String getFileContents(){
            return readAssetsContent("jquery.js");
        }
    }
    
  2. Update WebView to enable JavaScript and to add JavaScriptInterface defined previously...

    webView.getSettings().setJavaScriptEnabled(true);       
    webView.addJavascriptInterface(new JavaScriptInterface(), "android");
    
  3. Add javascript code snippet in your remote HTML to read the jquery file content through android JavaScript Interface...

    <script type="text/javascript">
    var s = document.createElement('script');
    s.innerHTML = window.android.getFileContents();
    document.head.appendChild(s);
    
    //check if jquery is loaded now...
    if(typeof $ != "undefined") {
        $(document).ready(function() {
            $('body').css('background','green');
        });
    } else {
        document.body.innerText = "jQuery NOT loaded";
    }
    </script>
    
Sign up to request clarification or add additional context in comments.

1 Comment

Where is this function readAssetsContent() ?? Do I have to create this or is this a library one ?
3

First, in your Activity, create the static variable appContext, which holds the Application Context and function below:

 //Initialize Application Context
 private static Context appContext;

 //Get Application Context (for use in external functions)
    public static Context getContext() {
        return appContext;
    }

...and set the variable in onCreate(Bundle savedInstanceState):

     //Set application context (for use in external functions)
     appContext = this;

Second, create class in separate file below:

File: JavaScriptInterface.java

import android.content.Context;
import android.util.Log;
import android.webkit.JavascriptInterface;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;    

class JavaScriptInterface {        

    @JavascriptInterface
    public String getFileContents(String assetName){
        return readAssetsContent(MainActivity.getContext(), assetName);
    }

    //Read resources from "assets" folder in string
    public String readAssetsContent(Context context, String name) {
        BufferedReader in = null;
        try {
            StringBuilder buf = new StringBuilder();
            InputStream is = context.getAssets().open(name);
            in = new BufferedReader(new InputStreamReader(is));

            String str;
            boolean isFirst = true;
            while ( (str = in.readLine()) != null ) {
                if (isFirst)
                    isFirst = false;
                else
                    buf.append('\n');
                buf.append(str);
            }
            return buf.toString();
        } catch (IOException e) {
            Log.e("error", "Error opening asset " + name);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    Log.e("error", "Error closing asset " + name);
                }
            }
        }

        return null;
    }

}

Third, do not forget to initialize your Webview to use JavaScriptInterface:

     //Set JS interface from JS/HTML code execution
     mWebView.addJavascriptInterface(new JavaScriptInterface(), "android");

Fourth, call the android method getFileContents() to load the local resources in your HTML with JavaScript:

       <script type="text/javascript">
          var s = document.createElement('script');
          s.innerHTML = window.android.getFileContents('js/jquery.min.js');
          document.head.appendChild(s);

          //check if jquery is loaded now...
          if(typeof $ != "undefined") {
              $(document).ready(function() {
                    alert("jQuery is loaded!");
             });
          } else {
                alert("jQuery is NOT loaded!");
          }
       </script>

Note: the local resource in this example is in /assets/js/ sub-folder.

1 Comment

The most important check is that the jsInterface is in a separate file. Explanation is GODLIKE! It's just about what the question is about.
-1

In my html page i just added a tag like this.

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

When you load you url that will automatically load all the js files. I think this is help you.

3 Comments

Please leave a comment when you down vote an answer.
question says remote page. means there is no access to page source, otherwise it was piece of cake
I missed this answer because of the downvotes and it's a very legitimate answer in some cases (at least in mine). Took me one extra hour to find the (same) solution elsewhere.

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.