首頁  >  文章  >  web前端  >  在WebView中使用JavaScript的方法介紹

在WebView中使用JavaScript的方法介紹

青灯夜游
青灯夜游轉載
2021-01-08 18:35:335954瀏覽

在WebView中使用JavaScript的方法介紹

如果你想要載入的頁面中使用了JavaScript,你必須為你的WebView啟用JavaScript。一旦使能之後,你也可以自己建立介面在你的應用程式和JavaScript程式碼間進行互動。

可以透過getSettings()取得WebSettings,然後用setJavaScriptEnabled()使能JavaScript:

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

綁定JavaScript與Android程式碼

#當你為你的Android應用程式中的WebView專門開發一個網頁應用程式時,你可以建立你的JavaScript程式碼和你的客戶端的Android程式碼之間的介面。

例如,你可以用JavaScript程式碼呼叫Android程式碼中的方法,來展現一個對話框之類,而不是使用alert()方法(JS中的對話框方法)。

在JS和Android程式碼間綁定一個新的接口,需要呼叫 addJavascriptInterface()方法。

方法參數傳入一個Java物件實例和一個字串,該字串是一個名字(interface name,注意此接口不是通常所說的那個用來實現的接口,而是傳入的這個物件在JS中的別名),在JS程式碼中用此名字呼叫該Java物件的方法。

注意這個方法可以讓JS程式碼控制宿主程序,這是一個非常強大的特性,但是同時也存在一些安全性問題,因為進一步JS程式碼可以透過反射存取到注入物件的公有域。攻擊者可能會在HTML和JavaScript中包含了有威脅性的程式碼。

所以Android 4.1,API 17,也就是JELLY_BEAN 開始,只有被JavascriptInterface 註解識別的公有方法可以被JS程式碼存取。

另外,因為JS程式碼和Java物件在這個WebView所私有的後台執行緒交互,所以還需要注意線程安全性問題。

注意,與JS程式碼綁定的這個Java物件運行在另一個執行緒中,與創建它的執行緒不是一個執行緒。

注意,這個Java物件的域是無法存取的。

綁定JavaScript與Android程式碼的範例

例如可以定義這麼一個類別:

/** * 自定义的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();
        }
    }

然後將這個類別和你的WebView中的JS程式碼綁定:

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

給這個物件起的別名叫「Android」。

這個就創立了一個介面名,叫做“Android”,運行在WebView中的JS程式碼可以透過這個名字呼叫WebAppInterface類別中的showToast()方法:

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

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

#特別注意:需要設定chrome handler

兩個問題:

1、網頁按鈕按下後不出現JS對話框是因為沒有設定chrome handler,需要設定如下: 

// 如果不设置这个,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.呼叫Android程式碼的那個按鈕也沒有出現Toast是因為我把別名寫錯了(大小寫沒有註意)。

Android呼叫JavaScript程式碼

這個還比較簡單,需要呼叫的時候只需要一行程式碼:  

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

其中myFunction()是JS函數。

這裡要補充一下,如果JavaScript函數是帶參數的,那麼呼叫時要特別注意。

例如下面這個JS函數,在原來內容上加入一行:

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

註:其中content是自訂的標籤,html中有一個段落是:

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

那麼在Android程式碼中呼叫這個writeLine()函數時,就需要傳入一個字串參數,例如,想要傳入一個叫name的String:

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

還有就是要注意雙引號中的函數名一定不要寫錯。

程式實例

效果如下:

在WebView中使用JavaScript的方法介紹

#介面中包含一個TextView,旁邊一個Button,下面整個是一個WebView。

在WebView中載入了一個本機html文件,本地文件存放在assets資料夾中。

網頁中前四個按鈕呼叫的是JavaScript函數,顯示各種對話方塊。

SayHello按鈕呼叫Android程式碼中的一個方法,顯示一個Toast,如圖中所示。

為了證明Android也可以呼叫JS程式碼,最上方的Android Button按下後和「點擊這裡」那個按鈕的效果一致,都是出現JS的對話框。

Activity程式碼:

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檔案:

<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佈局檔案:

<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>

更多程式設計相關知識,請造訪:程式設計教學! !

以上是在WebView中使用JavaScript的方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:oschina.net。如有侵權,請聯絡admin@php.cn刪除