2012-04-02 14 views
8

Sto migrando un'applicazione web in una versione Android. Dopo aver ricevuto ed elaborato i dati JSON, ho una serie di oggetti Javascript che si trovano all'interno della pagina.Posso passare un oggetto Javascript a un WebView Android?

Come posso passare il contenuto completo di uno degli oggetti javascript "out" al contenitore webview per la visualizzazione utilizzando i controlli Android nativi?

Eventualmente, potrei creare un'interfaccia javascript con un metodo con parametri per ciascuna delle possibili proprietà dell'oggetto javascript, ma questo sembra essere eccessivamente pesante.

Qualcuno può aiutare con questo?

+1

Controlla risposte in discussione simile http://stackoverflow.com/questions/2250917/passing-a-javascript-object-using-addjavascriptinterface-on-android/32698399#32698399 –

risposta

15

Android WebView contiene un metodo chiamato addJavascriptInterface(Object obj, String interfaceName) che dovrebbe essere utile qui.

Utilizzando questo metodo, è possibile accedere all'oggetto obj aggiunto come interfaccia tramite codice JavaScript nella visualizzazione Web. Nel tuo caso, potresti passare un oggetto che ha un metodo setter che trasferisce alcuni oggetti JavaScript su Java.

Sarà comunque necessario creare il codice della colla che converte l'oggetto JavaScript nell'oggetto JSON. Per un approccio rapido, è sufficiente che l'interfaccia generi un oggetto JSONObject sul lato Java utilizzando una stringa JSON passata da JavaScript. La classe JSONObject in Java ha un costruttore che accetta una stringa contenente dati JSON. Quindi, è possibile passare il risultato stringificato direttamente a Java e creare l'oggetto in questo modo. Per esempio:

class JSInterface { 
    HashMap<String, JSONObject> mObjectsFromJS = new HashMap<String, JSONObject>(); 
    public void passObject(String name, String json) { 
     mObjectsFromJS.put(name, new JSONObject(json)); 
    } 
} 

//At some point, register using: 
mJSInterface = new JSInterface(); 
mWebView.addJavascriptInterface(mJSInterface, "Android"); 

Poi, sul lato JavaScript, nel gestore che ha un blob di unparsed JSON nella variabile jsonData:

Android.passObject("pageItems", jsonData); 

Ora, il vostro JSInterface sul lato Java avrà un JSONObject contenente gli elementi, a cui è possibile accedere utilizzando i getter forniti da JSONObject. Gli oggetti creati tramite la chiamata Javascript saranno nella mappa mObjectsFromJS. Ovviamente vorrete aggiungere ulteriori metodi di supporto alla classe JSInterface per consentire una migliore gestione degli oggetti.

Non ho compilato o testato nessuno di questi metodi, quindi potrebbe essere necessario modificarli un po 'per il corretto funzionamento. Ma spero che questo ti dia l'idea.

Tuttavia, se gli oggetti dispongono di un'interfaccia e di elementi dati coerenti, sarebbe più sensato creare semplicemente una semplice funzione di incollaggio JavaScript che associa le proprietà dell'oggetto JavaScript ai campi dell'oggetto Java-side utilizzando i metodi setter.

NOTA BENE Questo sta dando la capacità di codice remoto per attivare codice nativo sul dispositivo. Se non si ha il controllo completo sulle pagine/script caricati nello WebView, è necessario assicurarsi che il comportamento esposto da obj non consenta alcun exploit.

+0

Grazie Jason, Da quello che dici, non è possibile "semplicemente" passare l'oggetto javascript direttamente a una funzione java setter e aspettarsi che venga tradotto. Così, per riprendere, avrei bisogno di: - prendere il mio oggetto JSON e tornare di nuovo ad un JSON stringa codificata - passare la stringa codificata back up attraverso l'interfaccia JavaScript - decodificarlo in un oggetto Java Tutto ciò per poter accedere correttamente ai dati. Grazie per aver chiarito questo. – Simon

+0

Dopo aver provato a far funzionare questa risposta, ho scoperto che l'interfaccia javascript è completamente rotta nella v2.3.x di Android. Vergogna. – Simon

+0

cosa succede se voglio rendere la mia funzione Java un costruttore, quindi chiamerei ad es. 'var ob = new Android.MyObject()', come restituire un oggetto javascript nativo? – Michael

Problemi correlati