DevCorner620

DevCorner: WebView e metodi Java

Giuseppe Tripodi

Per la disperazione dei puristi Java (e qui in redazione ne conosciamo qualcuno), il mondo delle webapp sta crescendo a velocità incredibile. La diretta conseguenza  di questa tendenza è che oggi con HTML, CSS e Javascript è possibile realizzare progetti anche discretamente complessi che possono funzionare sul browser di qualsiasi dispositivo. Il risvolto della medaglia è che sono sempre di più gli sviluppatori che si trovano a lavorare su applicazioni “ibride”, composte in egual misura da webview e codice nativo.
Sebbene in questi casi possa avere senso appoggiarsi a piattaforme esterne come Apache Cordova (molto conosciuto anche grazie alla distribuzione PhoneGap), non sempre è necessario aggiungere questo livello di complessità: per questo motivo nel DevCorner di oggi vi spieghiamo come far comunicare una webview con codice nativo di Android e viceversa.

Per prima cosa costruiamo la nostra interfaccia: posizioniamo nella parte alta del layout un campo di testo (in cui digitare del testo da inviare a Javascript) e un bottone per eseguire l’azione. Subito sotto una webview, che andremo a riempire con un file HTML caricato negli assets, che presenta un titolo, un paragrafo (da rimpiazzare con la stringa presente nell’EditTex) e due tasti, per mostrare rispettivamente un Toast e una Dialog.

L’XML del Layout dovrebbe quindi assomigliare a qualcosa del genere:



    

Mentre il nostro HTML (con Javascript incluso!) sarà simile a quanto segue:



DevCorner Example

Rimpiazzami!


Come potete notare, le due funzioni che devono richiamare codice nativo si appoggiano ad un oggetto chiamato “AndroidFunction” del quale discuteremo tra poco; il metodo per sostituire l’HTML del <p> con id testP, invece è chiamato callFromActivity. Per far sì che quest’ultimo funzioni, è sufficiente associare al bottone nativo “Invia a Javascript” il metodo loadURL della nostra webView: chiamando la funzione e aggiungendo la stringa prelevata dall’EditText si riesce a raggiungere facilmente il risultato.

Quindi la definizione dell’OnClickListenere sarà più o meno come segue:

            myEditText = (EditText) rootView.findViewById(R.id.msg);
            btnToJs = (Button) rootView.findViewById(R.id.sendmsg);
            btnToJs.setOnClickListener(new Button.OnClickListener() {

				@Override
				public void onClick(View arg0) {
					// TODO Auto-generated method stub
					String msgToSend = myEditText.getText().toString();
                    myWebView.loadUrl("javascript:callFromActivity(\""
							+ msgToSend + "\")");

				}
			});

La comunicazione da Javascript a Java è altrettanto elementare: per ottenere il risultato importiamo la classe JavascriptInterface di android.webkit e creiamo una nostra classe myJavascriptInterface (o come preferite voi!) alla quale passiamo il Context dell’Activity. All’interno definiamo i metodi Java che vogliamo richiamare dall’HTML (nel nostro caso showToast e OpenAndroidDialog) taggandoli con @JavascriptInterface, in questo modo:

		public class MyJavaScriptInterface {

			Context mContext;

			MyJavaScriptInterface(Context c) {
				mContext = c;
			}

			@JavascriptInterface
			public void showToast(String toast) {
				Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
			}

			@JavascriptInterface
			public void openAndroidDialog() {
				AlertDialog.Builder myDialog = new AlertDialog.Builder(mContext);
				myDialog.setTitle("Dialog!");
				myDialog.setMessage("Adesso ci credi?");
				myDialog.setPositiveButton("Ok", null);
				myDialog.show();
			}

		}

A questo punto non rimane altro che associare la JavascriptInterface alla webView, utilizzando AndroidFunction (il nome è arbitrario) come “collegamento” tra Javascript e Java

myWebView = (WebView) rootView.findViewById(R.id.mybrowser);

			final MyJavaScriptInterface myJavaScriptInterface = 
					new MyJavaScriptInterface(getActivity());

            myWebView.addJavascriptInterface(myJavaScriptInterface,
					"AndroidFunction");

            myWebView.getSettings().setJavaScriptEnabled(true);
            myWebView.loadUrl("file:///android_asset/index.html");

Anche per questa settimana con il DevCorner è tutto: come sempre, potete trovare l’intero codice sorgente nonché chiedere aiuto a proposito di questo o qualsiasi altro tutorial sulla sezione Sviluppo del nostro forum: buon divertimento con le webView, ma non vi ci abituate troppo!