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


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.