voglio sapere che se c'è un po 'di tempo prima che posso accedere al mio oggetto
Sì, penso che ci sia un ritardo, a causa WebView.addJavascriptInterface
verrà eseguito nel thread di lavoro interno del WebView. Forse ci hai pensato, e hai realizzato che WebView deve mantenere almeno un thread di lavoro per fare l'IO della rete asincrona. Forse hai notato questi thread anche in DDMS mentre usi una WebView.
Si scopre che utilizza anche una discussione per eseguire il lavoro per una serie di altri metodi pubblici. Mi piacerebbe davvero che i documenti di Google rendessero questo più chiaro! Ma spero di poterti aiutare e mostrarti come ho provato a confermarlo da solo.
Seguimi mentre guardo il sorgente di WebView. È ragionevolmente leggibile, anche se non è possibile seguire esattamente quello che sta succedendo, è possibile risalire attraverso alcune domande riguardo ai thread.
È possibile scaricare la fonte framework Android tramite lo strumento di gestione SDK, ma è anche speculare su Github, quindi è a questo che ho collegato qui. Ho indovinato e ho scelto un tag vicino ad alcune versioni di ICS. Non è difficile trovare . Ho solo cercato su Google "Sito WebView.java: github.com/android".
Il metodo WebView.addJavascriptInterface
invia un messaggio a un'istanza di WebViewCore
:
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
In WebViewCore.java
ci sono un sacco di metodi di overload chiamati sendMessage
, ma non abbiamo davvero bisogno di sapere che esattamente viene chiamato, dal momento che fanno praticamente la stessa cosa C'è anche un bel commento per darci un suggerimento sul fatto che siamo nel posto giusto! Tutti loro delegano a un'istanza di EventHub
che è una classe interna. This method risulta essere sincronizzato e sta inviando un messaggio a un'istanza di Handler
, che è una buona indicazione che probabilmente è in esecuzione in un'altra discussione, ma per completezza, scopriamolo!
Questo Handler
viene creata un'istanza in EventHub.transferMessages
che viene chiamato da WebViewCore.initialize
. Ci sono alcuni più luppolo qui, ma alla fine ho scoperto che questo è chiamato da run
in WebCoreThread
(sottoclasse di Runnable
), che viene istanziato insieme a un nuovo Thread
a destra here.
Che avventura! Quindi, anche se non posso davvero dire con certezza cosa sta succedendo con tutte queste parti mobili, sono abbastanza sicuro di dire che questo metodo non è sincrono e invia un messaggio al thread di lavoro di WebView. Spero che abbia un senso!
se sì, come faccio a sapere quanto tempo devo aspettare per chiamare il mio oggetto?
Purtroppo, non conosco la risposta a questo. Stavo cercando questo esatto problema e ho trovato questa domanda su StackOverflow nel corso del mio googling. Penso che tu abbia le seguenti opzioni, alcune delle quali sono più belle o più semplici di altre:
1) Solo Thread.sleep
per 100 ms o qualcosa tra addJavascriptInterface
e loadUrl("javascript:...")
. Blech, non mi piace, ma è potenzialmente il più facile.
2) Un'altra possibilità è che è possibile chiamare WebView.loadUrl
con uno snippet di JavaScript che verifica specificamente se l'interfaccia è impostata e rileva l'Eccezione di riferimento che viene generata se non è stata ancora impostata. Tuttavia, come avrai intuito, questo tipo comporta l'aggiunta di un'interfaccia JavaScript alla WebView!
3) Chiama invece il numero WebView.setWebChromeClient
e recupera JavaScript alert()
o console.log
. Dai miei esperimenti, questo metodo è sincrono, quindi non c'è alcun ritardo. (L'ho confermato alla fonte, ma lascerò i dettagli come esercizio per il lettore) Probabilmente dovresti inventare una stringa speciale per chiamare lo alert
e controllarlo all'interno di onJsAlert
, quindi non stai solo prendendo tutto il alert()
S.
Ci scusiamo per la lunghezza di questa risposta, spero che aiuti. In bocca al lupo!
Buona risposta elaborato con riferimenti appropriati. –
cool. bella risposta Ma controllare gli avvisi e i messaggi della console sono altrettanto brutti di Thread.sleep() :) – Akshat
Ehi, ma ho avvertito che le opzioni non sono ottimali: P – spacemanaki