Home  >  Article  >  Web Front-end  >  Introduction to using JavaScript in WebView

Introduction to using JavaScript in WebView

青灯夜游
青灯夜游forward
2021-01-08 18:35:336020browse

Introduction to using JavaScript in WebView

If the page you want to load uses JavaScript, you must enable JavaScript for your WebView. Once enabled, you can also create your own interfaces to interact between your application and JavaScript code.

You can get WebSettings through getSettings(), and then use setJavaScriptEnabled() to enable JavaScript:

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

Bind JavaScript and Android code

When you When developing a web app specifically for the WebView in your Android app, you can create an interface between your JavaScript code and your client-side Android code.

For example, you can use JavaScript code to call methods in Android code to display a dialog box or the like, instead of using the alert() method (dialog box method in JS).

To bind a new interface between JS and Android code, you need to call the addJavascriptInterface() method.

The method parameters pass in a Java object instance and a string. The string is a name (interface name. Note that this interface is not the interface commonly used to implement, but the one passed in. The alias of the object in JS), use this name to call the method of the Java object in the JS code.

Note that this method allows JS code to control the host program, which is a very powerful feature, but there are also some security issues, because further JS code can access the public domain of the injected object through reflection. Attackers may include threatening code in HTML and JavaScript.

So starting from Android 4.1, API 17, which is JELLY_BEAN, only the public methods identified by the JavascriptInterface annotation can be accessed by JS code.

In addition, because JS code and Java objects interact in the background thread private to this WebView, you also need to pay attention to thread safety issues.

Note that the Java object bound to the JS code runs in another thread, not the same thread as the thread that created it.

Note that the domain of this Java object is inaccessible.

Example of binding JavaScript and Android code

For example, you can define such a class:

/** * 自定义的Android代码和JavaScript代码之间的桥梁类
     * 
     * @author 1
     * */ public class WebAppInterface
    {
        Context mContext; 
        /** Instantiate the interface and set the context */ 
        WebAppInterface(Context c)
        {
            mContext = c;
        } /** Show a toast from the web page */ 
        // 如果target 大于等于API 17,则需要加上如下注解 
        // @JavascriptInterface public void showToast(String toast)
        { 
        // Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();  
        Toast.makeText(mContext, toast, Toast.LENGTH_LONG).show();
        }
    }

Then combine this class with the one in your WebView JS code binding:

WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");

The alias given to this object is "Android".

This creates an interface name called "Android". The JS code running in WebView can call the showToast() method in the WebAppInterface class through this name:

<input type="button" value="Say hello" 
onClick="showAndroidToast(&#39;Hello Android!&#39;)" />

<script type="text/javascript"> function showAndroidToast(toast) 
    {
        Android.showToast(toast);
    } </script>

Special note: chrome handler needs to be set

Two questions:

1. The JS dialog box does not appear after the web button is pressed because the chrome handler is not set. It needs to be set as follows:

// 如果不设置这个,JS代码中的按钮会显示,但是按下去却不弹出对话框 
// Sets the chrome handler. This is an implementation of WebChromeClient 
// for use in handling JavaScript dialogs, favicons, titles, and the
// progress. This will replace the current handler. 
myWebView.setWebChromeClient(new WebChromeClient()
        {

            @Override public boolean onJsAlert(WebView view, String url,
             String message,
                    JsResult result)
            { // TODO Auto-generated method stub return super.
            onJsAlert(view, url, message, result);
            }

        });

2. The button that calls the Android code does not show Toast because I wrote the alias wrong (I didn’t pay attention to the capitalization).

Android calls JavaScript code

This is relatively simple. When you need to call it, you only need one line of code:

myWebView.loadUrl("javascript:myFunction()");

where myFunction() is a JS function .

I would like to add here that if the JavaScript function takes parameters, special attention should be paid when calling it.

For example, the following JS function adds a line to the original content:

function writeLine(string)
    {
        console.log("Write a new Line");
        //调试信息 
        document.getElementById("content").innerHTML += string + 
        "<br />";
        //在content标签段落加入新行 
        }

Note: content is a custom tag, and there is a paragraph in html:

<p id="content"></p>

Then when calling this writeLine() function in Android code, you need to pass in a string parameter. For example, if you want to pass in a String called name:

myWebView.loadUrl("javascript:writeLine(&#39;"+name+"&#39;)");
//JS代码要是带参数

Also, pay attention to the function in double quotes. Be sure not to spell your name incorrectly.

Program Example

The effect is as follows:

Introduction to using JavaScript in WebView

The interface contains a TextView, a Button next to it, and the entire is a WebView.

A local html file is loaded in WebView, and the local file is stored in the assets folder.

The first four buttons in the web page call JavaScript functions to display various dialog boxes.

The SayHello button calls a method in the Android code to display a Toast, as shown in the figure.

In order to prove that Android can also call JS code, the top Android Button has the same effect as the "Click Here" button when pressed, and a JS dialog box appears.

Activity code:

package com.example.hellowebjs; 
import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.View; 
import android.webkit.JsResult; 
import android.webkit.WebChromeClient; 
import android.webkit.WebSettings; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 
import android.widget.Button; 
import android.widget.Toast; 
public class WebJSActivity extends Activity
{ private WebView myWebView = null; private Button myButton = null;

    @SuppressLint("SetJavaScriptEnabled")
    @Override public void onCreate(Bundle savedInstanceState)
    { super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_js);

        myWebView = (WebView) findViewById(R.id.myWebView); 
        // 得到设置属性的对象 
        WebSettings webSettings = myWebView.getSettings(); 
        // 使能JavaScript 
        webSettings.setJavaScriptEnabled(true); 
        // 支持中文,否则页面中中文显示乱码
         webSettings.setDefaultTextEncodingName("GBK"); 
         // 限制在WebView中打开网页,而不用默认浏览器 
         myWebView.setWebViewClient(new WebViewClient()); 
         // 如果不设置这个,JS代码中的按钮会显示,但是按下去却不弹出对话框 
         // Sets the chrome handler. 
         //This is an implementation of WebChromeClient 
         // for use in handling JavaScript dialogs, favicons, 
         //titles, and the 
         // progress. This will replace the current handler. 
         myWebView.setWebChromeClient(new WebChromeClient()
        {

         @Override public boolean onJsAlert(WebView view, String url, 
         String message,
                    JsResult result)
            { // TODO Auto-generated method stub return 
            super.onJsAlert(view, url, message, result);
            }

        }); 
        // 用JavaScript调用Android函数: 
        // 先建立桥梁类,将要调用的Android代码写入桥梁类的public函数
         // 绑定桥梁类和WebView中运行的JavaScript代码 
         // 将一个对象起一个别名传入,在JS代码中用这个别名代替这个对象,
         可以调用这个对象的一些方法 
         myWebView.addJavascriptInterface(new WebAppInterface(this), 
         "myInterfaceName"); 
         // 载入页面:本地html资源文件 
         myWebView.loadUrl("file:///android_asset/sample.html"); 
         // 这里用一个Android按钮按下后调用JS中的代码 
         myButton = (Button) findViewById(R.id.button1);
        myButton.setOnClickListener(new View.OnClickListener()
        {

            @Override public void onClick(View v)
            {
            // 用Android代码调用JavaScript函数: 
            myWebView.loadUrl("javascript:myFunction()"); 
            // 这里实现的效果和在网页中点击第一个按钮的效果一致  }
        });

    } /** * 自定义的Android代码和JavaScript代码之间的桥梁类
     * 
     * @author 1
     * */ public class WebAppInterface
    {
        Context mContext; 
        /** Instantiate the interface and set the context */ 
        WebAppInterface(Context c)
        {
            mContext = c;
        } /** Show a toast from the web page */ 
        // 如果target 大于等于API 17,则需要加上如下注解 
        // @JavascriptInterface public void showToast(String toast)
        { // Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); 
         Toast.makeText(mContext, toast, Toast.LENGTH_LONG).show();
        }
    }

}

HTML file:

<html> <head> <h1> This is a HTML Page </h1> 
<!-- JavaScript脚本,主要包括了按钮要执行的函数,显示对话框等 --> 
<script type="text/javascript"> 
//JavaScript方法,弹出对话框显示信息 
function myFunction()
    {
        alert("Hello World!");
    } function onAlert()
    {
        console.log("onAlert method");
        //显示调试信息  
alert("This is a alert sample from html");
    } function onConfirm()
    {
        console.log("onConfirm method"); 
        var b = confirm("are you sure to login?");
        alert("your choice is " + b);
    } function onPrompt()
    {
        console.log("onPrompt method"); 
        var b = prompt("please input your password", "aaa");
        alert("your input is " + b);
    } //调用绑定的Java对象的方法,即调用Android代码显示对话框 
  function showAndroidToast(toast)
    {
        console.log("showAndroidToast method");
        myInterfaceName.showToast(toast);
        //注意此处的myInterfaceName要和外部传入的名字一致,大小写正确 
         } 
         </script> 
         </head> 
         <body> 
         <p>
          <!-- 前四个按钮调用JS函数 -->
           JavaScript函数调用
           <br /> 
           <button onclick="myFunction()">点击这里!</button> 
           <br /> 
           <input type="button" value="alert" onclick="onAlert()" /> 
           <br /> 
           <input type="button" value="confirm" onclick="onConfirm()" />
            <br /> 
            <input type="button" value="prompt" onclick="onPrompt()" />
            <br /> 
            <!-- 上面用了两种定义按钮的方式,效果一样的 -->
              </p> 
              <p> 
              <!-- 这个Say hello 按钮调用Android代码中的方法 --> 
              用JavaScript按钮调用Android代码
               <br />
      <input type="button" value="Say hello" 
      onClick="showAndroidToast(&#39;Hello Android!&#39;)" /> 
      </p> 
      <a href="http://www.google.com" />Google </a> 
      </body> </html>

Activity layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/myRelativeLayout" 
android:layout_width="match_parent" 
android:layout_height="match_parent" > 
<TextView android:id="@+id/textView1" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:padding="@dimen/padding_medium" 
android:text="@string/hello_world" tools:context=".WebJSActivity" /> 
<Button android:id="@+id/button1" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_toRightOf="@id/textView1"
 android:text="@string/btn1_text" />
  <WebView android:id="@+id/myWebView" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:layout_below="@id/textView1" /> 
  </RelativeLayout>

For more programming related knowledge, please visit: Programming teaching! !

The above is the detailed content of Introduction to using JavaScript in WebView. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:oschina.net. If there is any infringement, please contact admin@php.cn delete