एक ही थ्रेड त्रुटि पर WebView विधियाँ


84

मेरे पास एक एंड्रॉइड प्रोग्राम है (एक वेबव्यू में जावा + एचटीएमएल)। मैं जावास्क्रिप्ट से जावा कोड पर कॉल कर सकता हूं। लेकिन दूसरे तरीके से काम करना बंद कर दिया (ग्रहण में अपडेट होने के बाद)।

तो यह मैं करने की कोशिश कर रहा हूँ

  • एक वेबव्यू बनाएं (काम किया)
  • AndroidFunction.test () को जावास्क्रिप्ट में कॉल करना; (काम)
  • जावा परीक्षण () फ़ंक्शन कॉल webView.loadUrl ("जावास्क्रिप्ट: हैलोब्लॉक ()"); (और काम नहीं कर रहा है)

मैंने इसे MainActivity में WebView के साथ काम करने देने की कोशिश की, लेकिन यह काम नहीं किया।

MainActivity.java

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final WebView webView = (WebView)findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebChromeClient(new WebChromeClient());
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        javascr = new Javascript(this, webView);
        webView.addJavascriptInterface(javascr, "AndroidFunction");
        webView.loadUrl("file:///android_asset/www/index.html");

        ....
}

Javascript.java

public class Javascript {   
    Context cont;
    WebView webView;

    Javascript(Context c, WebView w) {
        cont = c;
        webView = w;
    }

    // function called in the javascript by AndroidFunction.test();
    public void test() {
          // Breaking point!!!
        webView.loadUrl("javascript:helloBack()");
    }

त्रुटि:

03-24 11:47:50.103: W/WebView(21026):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
03-24 11:47:50.103: W/WebView(21026):   java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper{41ab68f8} called on Looper{41bb70a8}, FYI main Looper is Looper{41ab68f8})

03-24 11:47:50.103: W/WebView(21026):   at android.webkit.WebView.checkThread(WebView.java:2063)
03-24 11:47:50.103: W/WebView(21026):   at android.webkit.WebView.loadUrl(WebView.java:794)
03-24 11:47:50.103: W/WebView(21026):   at com.example.hellobt.Javascript.test(Javascript.java:24)

03-24 11:47:50.103: W/WebView(21026):   at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
03-24 11:47:50.103: W/WebView(21026):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
03-24 11:47:50.103: W/WebView(21026):   at android.os.Handler.dispatchMessage(Handler.java:102)

03-24 11:47:50.103: W/WebView(21026):   at android.os.Looper.loop(Looper.java:137)
03-24 11:47:50.103: W/WebView(21026):   at android.os.HandlerThread.run(HandlerThread.java:61)

जवाब के लिए धन्यवाद। मैंने अपनी जावास्क्रिप्ट फ़ाइल में फ़ंक्शन को इस तरह संपादित किया:

private void test(final String s) {
        webView.post(new Runnable() {
            public void run() {
                webView.loadUrl("javascript:" + s + ";");
            }
        });
        System.out.println("javscript done..");
    }

अपने संपादन में आप यह उल्लेख करते हैं कि आपने उत्तर (एक) के आधार पर अपना कोड बदल दिया है, जिससे यह लगता है कि इस तरह से ध्वनि अभी भी आपकी समस्या हल नहीं हुई है - लेकिन एक स्वीकृत उत्तर है। मेरा सुझाव है कि आप यह स्पष्ट कर दें कि क्या इससे समस्या हल हुई या नहीं (या सिर्फ संपादन को पूर्ववत करें)।
टॉम

जवाबों:


212

जावास्क्रिप्ट पद्धति को एक पृष्ठभूमि (यानी गैर-यूआई) थ्रेड पर निष्पादित किया जाता है। आपको यूआई थ्रेड पर सभी एंड्रॉइड व्यू संबंधित तरीकों को कॉल करने की आवश्यकता है। आप जो कुछ भी चाहते हैं उसे प्राप्त कर सकते हैं:

mWebView.post(new Runnable() {
    @Override
    public void run() {
        mWebView.loadUrl(...).
    }
});

जो UI थ्रेड पर चलने के लिए कार्य को पोस्ट करेगा।


आपने स्निपेट (mWebView) को अपने मूल कोड में कहां जोड़ा है?
बोवी

परीक्षण () फ़ंक्शन में, मेरे उपरोक्त प्रश्न को देखें।
जोहान होक्समा

क्या होगा यदि आपको एक मूल्य वापस करने की आवश्यकता है? जैसे रिटर्न webview.getUrl? stackoverflow.com/questions/29748782/… @JohanHoeksma
सुरेश

क्या आप जानते हैं कि यह समस्या कैसे और कब हुई? मेरे Nexus 5X (Android 7.1.1) में, यह ठीक है, लेकिन कुछ डिवाइस क्रैश हो गए।
ऐली ज़ो

कैसे एक चर पारित करने के लिए? मैंने mWebView.loadUrl ("जावास्क्रिप्ट: परीक्षण: (" "+ MyData +" ");") में चर जोड़ने की कोशिश की; लेकिन मूल्य कभी जावास्क्रिप्ट को पारित नहीं किया जाता है!
user1788736

14

मेरे मामले में एक WebView में कुछ भी नहीं दिखाया गया था, इसलिए मैं एक और तरीका पसंद करता हूं:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        final WebView webView = (WebView) findViewById(R.id.map);
        webView.loadDataWithBaseURL(...);
    }
});

3

पोस्ट विधि का उपयोग करके इसे खत्म किया जा सकता है। कृपया नीचे दिए गए कोड से जाएं।

 m_targetView.post(new Runnable() {
                        @Override
                        public void run() {
                            m_targetView.loadUrl(".....");
                        }
                    });

2

जावा संस्करण: आपको रननेबल इंटरफ़ेस और पोस्ट टू हैंडलर का उपयोग करना होगा ।

webView.post(new Runnable() {
          @Override
          public void run() {
             webView.loadUrl("file:///android_asset/www/index.html");
          }
       });

कोटलिन संस्करण:

webView.post(new Runnable {
   webView.loadUrl("file:///android_asset/www/index.html")
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.