WebView에서 JavaScript 사용 소개

青灯夜游
풀어 주다: 2021-01-08 18:35:33
앞으로
6015명이 탐색했습니다.

WebView에서 JavaScript 사용 소개

로드하려는 페이지가 JavaScript를 사용하는 경우 WebView에 대해 JavaScript를 활성화해야 합니다. 활성화되면 애플리케이션과 JavaScript 코드 간에 상호 작용하는 고유한 인터페이스를 만들 수도 있습니다.

getSettings()를 통해 WebSettings를 가져온 다음 setJavaScriptEnabled()를 사용하여 JavaScript를 활성화할 수 있습니다.

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
로그인 후 복사

Android 코드와 JavaScript 바인딩

Android 애플리케이션에서 WebView용으로 특별히 웹 애플리케이션을 개발할 때 JavaScript 코드와 클라이언트의 Android 코드 사이에 인터페이스를 만들 수 있습니다.

예를 들어, Alert() 메서드(JS의 대화 상자 메서드)를 사용하는 대신 JavaScript 코드를 사용하여 Android 코드의 메서드를 호출하여 대화 상자 등을 표시할 수 있습니다.

JS와 Android 코드 사이에 새로운 인터페이스를 바인딩하려면 addJavascriptInterface() 메서드를 호출해야 합니다.

메서드 매개변수는 Java 객체 인스턴스와 문자열을 전달합니다. 문자열은 이름(인터페이스 이름. 이 인터페이스는 구현에 일반적으로 사용되는 인터페이스가 아니라 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 핸들러를 설정해야 합니다

두 개 질문:

1. 크롬 핸들러가 설정되지 않았기 때문에 웹 페이지에서 버튼을 누른 후 JS 대화 상자가 나타나지 않습니다.

// 如果不设置这个,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. Wrong이라는 별칭을 썼기 때문에 토스트가 없습니다(대문자 사용에 주의하지 않음).

JavaScript 코드를 호출하는 Android

이것은 비교적 간단합니다. 호출해야 할 경우 코드 한 줄만 있으면 됩니다.

myWebView.loadUrl("javascript:myFunction()");
로그인 후 복사

myFunction()은 JS 함수입니다.

여기서 JavaScript 함수가 매개변수를 사용하는 경우 호출 시 특별한 주의를 기울여야 한다는 점을 덧붙이고 싶습니다.

예를 들어 다음 JS 함수는 원본 콘텐츠에 한 줄을 추가합니다.

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

참고: 콘텐츠는 맞춤 태그이고 html에 단락이 있습니다.

<p id="content"></p>
로그인 후 복사

그런 다음 Android 코드에서 이 writeLine() 함수를 호출하면 , 예를 들어 name이라는 문자열을 전달하려는 경우 문자열 매개변수를 전달해야 합니다.

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

또한 함수 이름을 큰따옴표로 잘못 쓰지 않도록 주의하세요.

프로그램 예

효과는 다음과 같습니다.

WebView에서 JavaScript 사용 소개

인터페이스에는 TextView, 옆에 Button, 아래에 WebView가 포함되어 있습니다.

WebView에는 로컬 html 파일이 로드되고, 로컬 파일은 자산 폴더에 저장됩니다.

웹페이지의 처음 4개 버튼은 JavaScript 함수를 호출하여 다양한 대화 상자를 표시합니다.

SayHello 버튼은 그림과 같이 Android 코드의 메서드를 호출하고 토스트 메시지를 표시합니다.

Android도 JS 코드를 호출할 수 있음을 증명하기 위해 상단의 Android 버튼을 눌렀을 때 "여기를 클릭하세요" 버튼과 동일한 효과를 가지며 JS 대화 상자가 나타납니다.

활동 코드:

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>
로그인 후 복사

활동 레이아웃 파일:

<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으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿