2012-06-09 8 views
21

मुझे लगता है कि जावा के लिए जावास्क्रिप्ट से बातचीत करने के लिए पता है कि तुम वेबव्यू में addjavascriptInterface विधि का उपयोग कर एक जावा वस्तु इंजेक्षन करने के लिए है।समझौता Android के वेबव्यू addjavascriptinterface

यहां समस्या है जिसका सामना कर रहा हूं।

  1. मैं addJavascriptInterface पद्धति का उपयोग करके मेरी जे एस में उपलब्ध होने की एक जावा वस्तु रजिस्टर।

  2. मैं webview.loadURL("javascript:XXX");

  3. का उपयोग कर वेबव्यू में कुछ जे एस इंजेक्षन मैं एक जे एस घटना भेज जब मैं जे एस इंजेक्शन लगाने के साथ किया हूँ।

समस्या यह है कि अगर तुरंत चरण 1 के बाद, अगर मैं निम्नलिखित जावास्क्रिप्ट निष्पादित है:

mWebView.loadUrl("javascript:if(window.myobject) console.log('myobject found---------'); else {console.log('myobject not found----');}"); 

मैं मेरे कंसोल के लॉग में "MyObject नहीं मिला"।

मुझे पता है कि अगर वहाँ कुछ समय है इससे पहले कि मैं अपने वस्तु का उपयोग कर सकते हैं और यदि हां, तो मैं कैसे पता करने के लिए मैं अपने वस्तु कॉल करने के लिए इंतजार करना चाहिए कितना समय मिलता है करना चाहते हैं?

उत्तर

44

मुझे पता है कि अगर वहाँ कुछ समय है इससे पहले कि मैं अपने वस्तु

उपयोग कर सकते हैं हाँ, मुझे लगता है कि एक देरी है, क्योंकि WebView.addJavascriptInterface WebView के आंतरिक कार्यकर्ता सूत्र में चलेंगे चाहते हैं। शायद आपने इस बारे में सोचा है, और महसूस किया है कि WebView को कम से कम एक कार्यकर्ता थ्रेड को एसिंक्रोनस नेटवर्क IO करने के लिए बनाए रखना है। हो सकता है कि आपने WebView का उपयोग करते समय डीडीएमएस में इन धागे को भी देखा हो।

ऐसा लगता है कि यह भी अन्य सार्वजनिक तरीकों की एक संख्या के लिए काम करने के लिए एक धागा उपयोग करता है। मैं सचमुच चाहता हूं कि Google के दस्तावेज़ों ने यह स्पष्ट किया हो! लेकिन मुझे आशा है कि मैं आपकी मदद कर सकता हूं और आपको दिखा सकता हूं कि मैंने अपने लिए यह पुष्टि करने का प्रयास कैसे किया।

मेरा अनुसरण करें क्योंकि मैं वेबव्यू के स्रोत को देखता हूं। यह उचित रूप से पठनीय है, भले ही आप जो भी हो रहा है उसका पालन नहीं कर सकते हैं, थ्रेड के संबंध में कुछ प्रश्नों के उत्तर के माध्यम से पता लगाना संभव है।

आप एसडीके प्रबंधक उपकरण के माध्यम से एंड्रॉयड ढांचे स्रोत डाउनलोड कर सकते हैं, लेकिन यह भी Github पर नजर आता है, इसलिए है कि क्या मैं यहाँ से जुड़ा हुआ है। मैंने अनुमान लगाया और एक टैग चुना जो आईसीएस के कुछ संस्करण के करीब है। ढूंढना मुश्किल नहीं है। मैं सिर्फ "WebView.java साइट: github.com/android" Googled।

विधि WebView.addJavascriptInterfaceWebViewCore का एक उदाहरण के लिए एक संदेश भेजता है:

mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg); 

WebViewCore.java में देखते हैं अतिभारित तरीकों sendMessage कहा जाता है का एक समूह है, लेकिन हम वास्तव में यह जानना चाहेंगे कि कहा जाता है की जा रही है जो जरूरत नहीं है, चूंकि वे एक ही चीज़ करते हैं। हमें एक संकेत देने के लिए एक अच्छी टिप्पणी भी है कि हम सही जगह पर हैं! वे सभी EventHub के उदाहरण के लिए प्रतिनिधि हैं जो कुछ आंतरिक वर्ग है। This method सिंक्रनाइज़ होने के लिए बाहर निकलता है, और Handler के उदाहरण के लिए एक संदेश भेज रहा है, जो एक अच्छा संकेत है कि यह शायद किसी अन्य धागे में चल रहा है, लेकिन पूर्णता के लिए, चलो पता लगाएं!

HandlerEventHub.transferMessages में तत्काल है जिसे WebViewCore.initialize से बुलाया जाता है। यहां कुछ और हॉप्स हैं, लेकिन आखिर में मुझे पता चला कि runWebCoreThread (Runnable के उप-वर्ग) से इसे Thread दाएं here के साथ तुरंत चालू किया गया है।

क्या एक साहसिक कार्य है! इसलिए, भले ही मैं वास्तव में यह नहीं कह सकता कि इन सभी चलती हिस्सों के साथ क्या चल रहा है, मुझे यह कहना बेहद आश्वस्त है कि यह विधि तुल्यकालिक नहीं है, और वेबव्यू के कार्यकर्ता धागे को एक संदेश भेजती है। मुझे उम्मीद है कि इसका कोई अर्थ है!

यदि हां, तो मुझे कैसे पता चलेगा कि मैं अपनी वस्तु को कॉल करने के लिए कितना समय इंतजार करूँ?

दुर्भाग्य से, मुझे इसका जवाब नहीं पता है। मैं इस सटीक मुद्दे पर शोध कर रहा था और मेरे गुगलिंग के दौरान स्टैक ओवरव्लो पर यह प्रश्न पाया। मुझे लगता है कि आप निम्नलिखित विकल्पों, जिनमें से कुछ अच्छे या दूसरों की तुलना में आसान हैं:

1) बस Thread.sleep 100 के लिए एमएस या कुछ addJavascriptInterface और loadUrl("javascript:...") के बीच। ब्लीच, मुझे यह पसंद नहीं है, लेकिन यह संभवतः सबसे आसान है।

2) एक और संभावना यह है कि आप जावास्क्रिप्ट के एक स्निपेट के साथ WebView.loadUrl पर कॉल कर सकते हैं जो विशेष रूप से इंटरफ़ेस सेट होने पर परीक्षण करता है, और संदर्भ त्रुटि को पकड़ता है जिसे अभी तक सेट नहीं किया गया है। हालांकि, जैसा कि आपने अनुमान लगाया होगा, इस तरह के वेबव्यू में एक जावास्क्रिप्ट इंटरफ़ेस जोड़ना शामिल है!

3) WebView.setWebChromeClient बजाय कॉल करें, और पकड़ने जावास्क्रिप्ट का alert() या console.log बजाय। मेरे प्रयोगों से, यह विधि तुल्यकालिक है, इसलिए कोई देरी नहीं है। (मैंने स्रोत में इसकी पुष्टि की है, लेकिन मैं पाठक के लिए अभ्यास के रूप में विवरण छोड़ दूंगा) आपको शायद alert पर कॉल करने के लिए कुछ विशेष स्ट्रिंग के साथ आना चाहिए और onJsAlert के अंदर इसकी जांच करनी चाहिए, इसलिए आप केवल alert() को पकड़ नहीं रहे हैं रों।

इस उत्तर की लंबाई के लिए खेद है, मुझे आशा है कि इससे मदद मिलेगी। सौभाग्य!

+0

अच्छा विस्तृत जवाब बदलने के लिए कोड

  • बहुत आसान तोड़ने स्ट्रिंग विभाजक के फिक्स्ड संभावना। –

  • +0

    ठंडा। अच्छा जवाब लेकिन अलर्ट और कंसोल संदेश जांचना उतना ही बुरा है जितना थ्रेड.sleep() :) – Akshat

    +0

    अरे, मैंने सभी को चेतावनी दी है कि विकल्प उप-शीर्ष हैं: पी – spacemanaki

    1

    अपने एचटीएमएल/जावास्क्रिप्ट में घोषित अपनी जावास्क्रिप्ट ऑब्जेक्ट्स को सुनिश्चित करें कि आपको जावा से एक्सेस करने की आवश्यकता है वैश्विक रूप से घोषित किया जाता है अन्यथा उन्हें अधिकतर एकत्रित किया जाएगा।

    <script> 
        var cb = function(location) { 
        alert('location is ' + location); 
        } 
        Android.getLocation('cb'); 
    </script> 
    

    getLocation विधि Android के LocationManager.requestSingleUpdate जो तब कॉलबैक जब LocationListener आग का आह्वान का आह्वान: मुझे लगता है कि यह करता है (जहां एंड्रॉयड मेरी इंटरफ़ेस addJavascriptInterface के साथ जोड़ा है) कोड है।

    "var" के बिना मुझे लगता है कि जब तक स्थान लुकअप कॉलबैक को आमंत्रित करता है तो कॉलबैक फ़ंक्शन कचरा एकत्रित किया गया है।

    0

    मैं लिया है (a similar question पर मेरी प्रतिक्रिया से नकल) जेसन शाह की और मेरे आकलन के लिए निर्माण खंड के रूप में श्री एस के कार्यान्वयन और बहुत इस पर सुधार हुआ है।

    इस टिप्पणी में डालने के लिए अभी तक बहुत अधिक कोड है, मैं बस इसे लिंक करूंगा।

    प्रमुख बिंदु इस प्रकार हैं:

    • जिंजरब्रेड (2.3.x) जे एस से
    • कॉल Android के सभी संस्करणों पर लागू होता है अब सिंक्रोनस
    • अब टी नहीं है ओ इंटरफ़ेस तरीकों नक्शा मैन्युअल
    • उचित संदर्भ के साथ जे एस हस्ताक्षर और इंटरफ़ेस नाम
    संबंधित मुद्दे