[javascript] WebView의 Android 호출 JavaScript 함수

내부에서 실행 javascript되는 html페이지에 앉아있는 일부 함수 를 호출하려고 합니다 android webview. 코드가 아래에서 수행하려는 작업은 매우 간단합니다 .Android 앱에서 javascript테스트 메시지가 있는 함수를 호출합니다. 테스트 메시지는 토스트를 통해 테스트 메시지를 표시하는 Android 앱에서 다시 Java 함수를 호출합니다.

javascript기능 외모가 좋아 :

function testEcho(message){
     window.JSInterface.doEchoTest(message);
}

WebView에서 javascript운없이 다음과 같은 방법으로 전화를 시도했습니다 .

myWebView.loadUrl("javascript:testEcho(Hello World!)");
mWebView.loadUrl("javascript:(function () { " + "testEcho(Hello World!);" + "})()");

나는 활성화 javascript했다WebView

myWebView.getSettings().setJavaScriptEnabled(true);
// register class containing methods to be exposed to JavaScript
myWebView.addJavascriptInterface(myJSInterface, "JSInterface"); 

그리고 여기에 Java클래스

public class JSInterface{

private WebView mAppView;
public JSInterface  (WebView appView) {
        this.mAppView = appView;
    }

    public void doEchoTest(String echo){
        Toast toast = Toast.makeText(mAppView.getContext(), echo, Toast.LENGTH_SHORT);
        toast.show();
    }
}

나는 내가 뭘 잘못하고 있는지 알기 위해 인터넷 검색에 많은 시간을 보냈다. 내가 찾은 모든 예제는이 접근법을 사용합니다. 여기에 잘못된 것이 있습니까?

편집 :javascript 에서 참조되고 사용되는 다른 외부 파일 이 몇 가지 있는데 html문제가 될 수 있습니까?



답변

문제가 무엇인지 알아 냈습니다 : testEcho () 매개 변수에 따옴표가 없습니다. 이것이 내가 전화하라는 방법입니다.

myWebView.loadUrl("javascript:testEcho('Hello World!')");


답변

kitkat부터는 다음과 같이 javascript 함수를 호출하기 위해 대신 loadUrl을 사용하십시오.

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        webView.evaluateJavascript("enable();", null);
    } else {
        webView.loadUrl("javascript:enable();");
    }


답변

public void run(final String scriptSrc) {
        webView.post(new Runnable() {
            @Override
            public void run() {
                webView.loadUrl("javascript:" + scriptSrc);
            }
        });
    }


답변

JavaScript 메소드를 호출하기위한 멋진 래퍼를 만들었습니다. 또한 로그에 JavaScript 오류가 표시됩니다.

private void callJavaScript(String methodName, Object...params){
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("javascript:try{");
    stringBuilder.append(methodName);
    stringBuilder.append("(");
    for (int i = 0; i < params.length; i++) {
        Object param = params[i];
        if(param instanceof String){
            stringBuilder.append("'");
            stringBuilder.append(param.toString().replace("'", "\\'"));
            stringBuilder.append("'");
        }
        if(i < params.length - 1){
            stringBuilder.append(",");
        }
    }
    stringBuilder.append(")}catch(error){Android.onError(error.message);}");
    webView.loadUrl(stringBuilder.toString());
}

이것도 추가해야합니다 :

private class WebViewInterface{

    @JavascriptInterface
    public void onError(String error){
        throw new Error(error);
    }
}

그리고이 인터페이스를 webview에 추가하십시오.

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewInterface(), "AndroidErrorReporter");


답변

예, 구문 오류가 있습니다. logcat에서 Javascript 오류 및 인쇄 명령문을 얻으 onConsoleMessage(ConsoleMessage cm)려면 WebChromeClient 에서 메소드를 구현해야합니다 . 웹 콘솔 (검사 요소)과 같은 완전한 스택 추적을 제공합니다. 방법은 다음과 같습니다.

public boolean onConsoleMessage(ConsoleMessage cm)
    {
        Log.d("Message", cm.message() + " -- From line "
                             + cm.lineNumber() + " of "
                             + cm.sourceId() );
        return true;
    }

구현 후에는 console.loglogcat에 Javascript 오류 및 인쇄 문 ( )이 표시됩니다.


답변

@Ilya_Gazman 답변 수정

    private void callJavaScript(WebView view, String methodName, Object...params){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("javascript:try{");
        stringBuilder.append(methodName);
        stringBuilder.append("(");
        String separator = "";
        for (Object param : params) {
            stringBuilder.append(separator);
            separator = ",";
            if(param instanceof String){
                stringBuilder.append("'");
            }
                stringBuilder.append(param.toString().replace("'", "\\'"));
            if(param instanceof String){
                stringBuilder.append("'");
            }

        }
        stringBuilder.append(")}catch(error){console.error(error.message);}");
        final String call = stringBuilder.toString();
        Log.i(TAG, "callJavaScript: call="+call);


        view.loadUrl(call);
    }

JS 호출을 올바르게 생성합니다.

callJavaScript(mBrowser, "alert", "abc", "def");
//javascript:try{alert('abc','def')}catch(error){console.error(error.message);}
callJavaScript(mBrowser, "alert", 1, true, "abc");
//javascript:try{alert(1,true,'abc')}catch(error){console.error(error.message);}

객체는 올바르게 전달되지 않지만 인수로 전달하기 전에 직렬화 할 수 있습니다.

또한 오류가 발생하는 위치를 변경했으며 오류를 콘솔 로그로 전환하여 다음과 같이들을 수 있습니다.

    webView.setWebChromeClient(new CustomWebChromeClient());

그리고 클라이언트

class CustomWebChromeClient extends WebChromeClient {
    private static final String TAG = "CustomWebChromeClient";

    @Override
    public boolean onConsoleMessage(ConsoleMessage cm) {
        Log.d(TAG, String.format("%s @ %d: %s", cm.message(),
                cm.lineNumber(), cm.sourceId()));
        return true;
    }
}


답변

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

MainActivity.java


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.bluapp.androidview.R;

public class WebViewActivity3 extends AppCompatActivity {
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view3);
        webView = (WebView) findViewById(R.id.webView);
        webView.setWebViewClient(new WebViewClient());
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("file:///android_asset/webview1.html");


        webView.setWebViewClient(new WebViewClient(){
            public void onPageFinished(WebView view, String weburl){
                webView.loadUrl("javascript:testEcho('Javascript function in webview')");
            }
        });
    }
}

자산 파일

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>WebView1</title>
<meta forua="true" http-equiv="Cache-Control" content="max-age=0"/>
</head>

<body style="background-color:#212121">
<script type="text/javascript">
function testEcho(p1){
document.write(p1);
}
</script>
</body>

</html>