ওয়েবভিউতে অ্যান্ড্রয়েড কলিং জাভাস্ক্রিপ্ট ফাংশন


249

আমি javascriptএকটি htmlপৃষ্ঠার ভিতরে চলমান কিছু ফাংশন কল করার চেষ্টা করছি android webview। কোডটি নীচে কী করার চেষ্টা করে তা খুব সহজ - অ্যান্ড্রয়েড অ্যাপ্লিকেশন থেকে, javascriptএকটি পরীক্ষা বার্তা সহ একটি ফাংশন কল করে , যা প্রবেশের মাধ্যমে জাভা ফাংশনটিকে আবার অ্যান্ড্রয়েড অ্যাপে কল করে যা টোস্টের মাধ্যমে পরীক্ষার বার্তা প্রদর্শন করে।

javascriptফাংশন দেখে মনে হচ্ছে:

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

ওয়েবভিউ থেকে আমি 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"); 

এবং heres 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, সেগুলি কি সমস্যা হতে পারে?


13
আপনি যে কোডটি জাভাস্ক্রিপ্টের পাশে মিস করেছেন উক্তি ব্যবহার করার চেষ্টা করছেন।
পল ডি ভ্রিজে

2
দয়া করে নোট করুন যে অ্যান্ড্রয়েড ৪.২ @JavascriptInterfaceথেকে আপনার জাভাস্ক্রিপ্ট ইন্টারফেসের মাধ্যমে ওয়েবভিউতে উপলব্ধ করতে চান এমন জাভা পদ্ধতিতে ডেকরেটার ব্যবহার করা দরকার।
ফ্রেড

1
কোড থেকে myWebView.loadUrl("javascript:testEcho('Hello World!')");আমি বুঝতে পারি যে আপনি ইতিমধ্যে এই HTML ভিউলে এইচটিএমএল ফাইল সংযুক্ত করেছেন। আপনি আমাকে বলতে পারেন যে আপনি এটি কিভাবে?
টনি_ক্রাফট

উত্তর:


195

আমি সমস্যাটি কী তা বুঝতে পেরেছি: টেস্টএকো () প্যারামিটারে উদ্ধৃতি নেই। এইভাবেই আমি কাজ করার জন্য কল পেয়েছি:

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

দয়া করে এই লিঙ্কে একটি চেহারা আছে stackoverflow.com/questions/9079374/...
kamal_tech_view

এটি দুর্দান্ত, তবে আপনি কীভাবে কোনও জাভা অবজেক্টকে একটি জাভাস্ক্রিপ্ট ফাংশনে যুক্তিরূপে পাস করবেন?
কোভ্যাকস ইম্রে

1
@ কোভ্যাকসআইমির স্ট্রিং.ফোরাম্যাট ("জাভাস্ক্রিপ্ট: টেস্টইচো ('% d', '% ডি', '% ডি'))", ১, ২, ৩); আমার ধারণা
ব্যবহারকারী 457015

ধন্যবাদ, আমি মাঝামাঝি সময়েও খুঁজে পেয়েছি।
কোভাকস ইম্রে

1
কিটকাট দিয়ে শুরু করে মূল্যায়ন করা জাভাস্ক্রিপ্ট
হিটার

117

কিটকাট থেকে নীচে জাভাস্ক্রিপ্ট ফাংশনগুলি কল করতে লোডআরল এর পরিবর্তে মূল্যায়ন করুন জাভাস্ক্রিপ্ট পদ্ধতি ব্যবহার করুন

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

2
লোডআরএল () এর পরিবর্তে মূল্যায়ন জাভাস্ক্রিপ্ট () কেন ব্যবহার করবেন?
কামরান বিগডেলি

2
@ কামি লোডআরল () পৃষ্ঠাটি পুনরায় লোড করবে এবং পেজে ফিনিশড () এ আবার কল করবে
Zach

1
@ জ্যাচ এটি তখনও প্রাক-কিটক্যাট নিয়ে একটি সমস্যা, তাই না?
ভেসেভলড গ্যানিন

2
@ কমি জাচের উত্তরে যুক্ত করে জাভাস্ক্রিপ্ট () মূল্যায়ন করুন, জাভাস্ক্রিপ্ট অ্যাসিঙ্ক্রোনালি চালাবেন। সুতরাং আমরা মূল্যায়ন জাভাস্ক্রিপ্ট () ব্যবহার করে ইউআই থ্রেড ব্লক করা এড়াতে পারি।
প্রসাদ

loadUrlআমি যখন কোনও ইনপুট ক্ষেত্রে মান পূরণ করার চেষ্টা করি তখন সফ্টওয়্যার কীবোর্ডটিও প্রদর্শন করে দেয়।
জোশুয়া

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

এবং যদি এটি কাজ না করে তবে নতুন থ্রেড করুন (নতুন রান্নেবল () {.. <উপরে যেমন> ..}) শুরু করুন ()
রাদু সিমিওনেসকু

26

আমি জাভাস্ক্রিপ্ট পদ্ধতি কল করতে একটি দুর্দান্ত মোড়ক তৈরি করেছি; এটি লগতে জাভাস্ক্রিপ্ট ত্রুটিগুলি দেখায়:

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.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewInterface(), "AndroidErrorReporter");

এই ফাংশনটি যদিও ধারণা হিসাবে ভাল তবে এটির ভুল প্রয়োগ রয়েছে। এই কলটি: final Object a = new Object(); callJavaScript(mBrowser, "alert", 1, true, "abc", a);এতে উত্পন্ন হবে যার SyntaxErrorসাথে Unexpected tokenআপনি উত্পন্ন javascript:try{alert(,,'abc',,)}catch(error){console.error(error.message);}
জেএস

এমনকি callJavaScript(mBrowser, "alert", "abc", "def");সর্বদা সহজ কলটি ত্রুটি তৈরি করে কারণ সর্বদা শেষে দুর্বৃত্ত কমা থাকে। আমার কাছ থেকে।
লুকাসজ 'সেভেরিয়ান' গ্রিলা

1
@ লুকাসজ'সেভারিয়া'গ্রেলা টিএনএক্স, আমি এটি স্থির করেছি। পিএস পরের বার অলস হবেন না আপনি
নিজেরাই

16
ভবিষ্যতের রেফারেন্সের জন্য: আসুন ইতিবাচক থাকুন। কোডটিতে একটি ত্রুটি দেখানো অলস নয়। এটি এখনও সহায়ক প্রতিক্রিয়া।
DW

আমার অনুমান যে প্যারামিটারের কোনওটিতে এর চরিত্র থাকলে এটি কাজ করবে না? উদাহরণ:callJavascript(mBrowser, "can't do it");
কোস্টানোস

18

হ্যাঁ আপনার সিনট্যাক্স ত্রুটি আছে। আপনি যদি আপনার জাভাস্ক্রিপ্ট ত্রুটিগুলি এবং আপনার লগকটে মুদ্রণ বিবরণী পেতে চান তবে আপনাকে অবশ্যই onConsoleMessage(ConsoleMessage cm)আপনার ওয়েবক্রোমক্লিয়েন্টে পদ্ধতিটি প্রয়োগ করতে হবে । এটি ওয়েব কনসোলের মতো সম্পূর্ণ স্ট্যাক ট্রেস দেয় (উপাদানটি পরীক্ষা করুন)। এই পদ্ধতিটি এখানে।

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

প্রয়োগের পরে আপনি আপনার জাভাস্ক্রিপ্ট ত্রুটি এবং মুদ্রণ বিবরণী ( console.log) আপনার লগকটে পাবেন।


2
আমি বিশ্বাস করি এটি ওয়েবক্রোমক্লিয়েন্টে রয়েছে এবং ওয়েবভিউক্লিয়েন্ট নয়।
মাইকেল লেভি

হ্যাঁ আপনি সঠিক @ মিশেললভি ঠিক আছে। ভুলটির জন্য আমাকে নির্দেশ করার জন্য ধন্যবাদ এখন আমি আমার উত্তর সম্পাদনা করেছি।
দীনেশ

1
ধন্যবাদ, আপনার উত্তরটি আমার প্রয়োজন মতো ছিল। আমি লোকদের ওয়েবক্রোমক্লিয়েন্টে জেএসআলার্ট () -কে ওভাররাইড করার পরামর্শ দিই। জাভাস্ক্রিপ্ট লগিং এবং সতর্কতার সংমিশ্রণটি ওয়েবভিউতে হোস্ট করা জাভাস্ক্রিপ্ট ডিবাগ করার সময় সত্যই সহায়ক হতে পারে।
মাইকেল লেভি

13

@ ইলিয়া_গাজমান উত্তরের পরিবর্তন

    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);
    }

সঠিকভাবে জেএস কলগুলি তৈরি করবে

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

ধন্যবাদ। এই পদ্ধতিটি কোনও পরিবর্তনকের অভ্যন্তরের চরিত্রটি থেকে বাঁচবে? অন্য কথায়, এটা দিয়ে কাজ হবে: callJavascript(mBrowser, "can't do it");?
Kostanos


2

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>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.