Android应用程序与JS双向调用

 

 

Android手机中内置了一款高性能webkit内核,该内核完美封装到了WebView组件中,而从js中直接调用java方法和在java中直接调用js方法更是让我们看到了WebView的强大,下面这个小例子介绍了怎样在js和java中双向调用方法 1.首先是布局文件main.xml Xml代码   

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <WebView  
  8.     android:layout_width="fill_parent"  
  9.     android:layout_height="fill_parent"  
  10.     android:id="@+id/webView"  
  11.     />  
  12. </LinearLayout>  

2.在assets目录下新建一个index.html文件 Html代码   

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  
  2.         "http://www.w3.org/TR/html4/loose.dtd">  
  3. <html>  
  4. <head>  
  5.   <title></title>  
  6.     <script type="text/javascript">  
  7.         //data数据类型为字符串,字符串里面是数组,每一个数组元素为一个json对象,例如"[{id:1,name:'张三',phone:'135656461'},{id:2,name:'李四',phone:'1896561'}]"  
  8.         function setContactInfo(data)  
  9.         {  
  10.             var tableObj = document.getElementById("contact");  
  11.             var jsonObjects = eval(data);   //通过eval方法处理得到json对象数组  
  12.             for(var i=0; i<jsonObjects.length; i++)  
  13.             {  
  14.                    var jsonObj = jsonObjects[i];    //获取json对象  
  15.                    var tr = tableObj.insertRow(tableObj.rows.length);   //添加一行  
  16.                    //添加三列  
  17.                    var td1 = tr.insertCell(0);  
  18.                    var td2 = tr.insertCell(1);  
  19.                    var td3 = tr.insertCell(2);  
  20.                      
  21.                    td1.innerHTML = jsonObj.id;  
  22.                    td2.innerHTML = jsonObj.name;  
  23.                    td3.innerHTML = jsonObj.phone;  
  24.             }  
  25.         }  
  26.   
  27.     </script>  
  28. </head>  
  29. <!--onload="javascript:myObject.init()调用服务器端init方法-->  
  30. <body onload="javascript:myObject.init()">  
  31.       <table id="contact">  
  32.           <tr>  
  33.               <td>编号</td>  
  34.               <td>姓名</td>  
  35.               <td>电话</td>  
  36.           </tr>  
  37.       </table>  
  38. </body>  
  39. </html>  

3.接着是Activity Java代码   

  1. package com.lamp.activity;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.webkit.WebView;  
  7.   
  8. public class HTMLActivity extends Activity {  
  9.     private WebView webView = null;  
  10.     public Handler handler = new Handler();  
  11.     @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.main);  
  15.           
  16.         webView = (WebView)this.findViewById(R.id.webView);  
  17.         //设置字符集编码  
  18.         webView.getSettings().setDefaultTextEncodingName("UTF-8");  
  19.         //开启JavaScript支持  
  20.         webView.getSettings().setJavaScriptEnabled(true);  
  21.         webView.addJavascriptInterface(new MyObject(this,handler), "myObject");  
  22.         //加载assets目录下的文件  
  23.         String url = "file:///android_asset/index.html";  
  24.         webView.loadUrl(url);  
  25.     }  
  26. }  

4.然后是绑定js的类MyObject Java代码   

  1. package com.lamp.activity;  
  2.   
  3. import org.json.JSONArray;  
  4. import org.json.JSONException;  
  5. import org.json.JSONObject;  
  6.   
  7. import android.os.Handler;  
  8. import android.webkit.WebView;  
  9.   
  10. public class MyObject {  
  11.     private Handler handler = null;  
  12.     private WebView webView = null;  
  13.   
  14.     public MyObject(HTMLActivity htmlActivity, Handler handler) {  
  15.         this.webView = (WebView)htmlActivity.findViewById(R.id.webView);  
  16.         this.handler = handler;  
  17.     }  
  18.       
  19.     public void init(){  
  20.         //通过handler来确保init方法的执行在主线程中  
  21.         handler.post(new Runnable() {  
  22.               
  23.             public void run() {  
  24.                 //调用客户端setContactInfo方法  
  25.                 webView.loadUrl("javascript:setContactInfo('" + getJsonStr() + "')");  
  26.             }  
  27.         });  
  28.     }  
  29.       
  30.     public static String getJsonStr(){  
  31.         try {  
  32.             JSONObject object1 = new JSONObject();  
  33.             object1.put("id", 1);  
  34.             object1.put("name", "张三");  
  35.             object1.put("phone", "123456");  
  36.               
  37.             JSONObject object2 = new JSONObject();  
  38.             object2.put("id", 2);  
  39.             object2.put("name", "李四");  
  40.             object2.put("phone", "456789");  
  41.               
  42.             JSONArray jsonArray = new JSONArray();  
  43.             jsonArray.put(object1);  
  44.             jsonArray.put(object2);  
  45.             return jsonArray.toString();  
  46.         } catch (JSONException e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.         return null;  
  50.     }  
  51. }  

运行项目,我们可以看到两位联系人的信息显示在了屏幕上
 android与javascript交互调用
分类: android_基础介绍2011-03-19 12:20 3718人阅读 评论(7) 收藏 举报
我们都知道,手机时代的来临的主要标志是啥?能够方便的接入互联网!互联网展现给我们的方式一般都是网页,网页中又必不可少的拥有javascript,所以说,android提供对javascript的支持那是迫在眉睫了,幸好,android早就给我们提供了无缝连接。让我们可以通过android与javascript进行交互。
我们的应用很简单,如图:

我们有一个输入框,旁边有个按钮,点击按钮就会提示我们输入的内容。当然这只是html中最简单的程序了,但是你将这个程序放入android手机中访问下试试,它是不会进行提示的。要想让其以android的形式提示用户,我们就需要用到android和javascript的交互。对了,这里展示的是一个网页哦,代码如下:
js.html
[xhtml:nogutter] view plaincopy


  1. <html>  
  2. <head>  
  3. <title>js交互android</title>  
  4. <mce:script type="text/javascript"><!--  
  5.       
  6.     function show(){  
  7.     var a = document.getElementById("text").value;  
  8.     alert(a);  
  9.       
  10.     }  
  11. // --></mce:script>  
  12. </head>  
  13. <body>  
  14. <form action="">  
  15.     <input type="text" id="text" value=""/>  
  16.     <input type="button" id="button" onclick="window.chenzheng_java.show()" value="clickme"/>  
  17.   
  18. </form>  
  19.   
  20. </body>  
  21. </html>  

再看看我们的activity代码:
[java:nogutter] view plaincopy


  1. package cn.com.chenzheng_java.js;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.util.Log;  
  7. import android.webkit.JsResult;  
  8. import android.webkit.WebChromeClient;  
  9. import android.webkit.WebSettings;  
  10. import android.webkit.WebView;  
  11. import android.widget.Toast;  
  12.   
  13. public class JavaScriptActivity extends Activity {  
  14.     WebView webView;  
  15.     Handler handler = new Handler();  
  16.   
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.   
  22.         webView = (WebView) findViewById(R.id.webView1);  
  23.         /**
  24.          * webSettings 保存着WebView中的状态信息。当WebView第一次被创建时,webSetting中
  25.          * 存储的都为默认值。WebSetting和WebView是一一绑定的。如果webView被销毁了,那么
  26.          * 我们再次调用webSetting中的方法时,会抛出异常。
  27.          */  
  28.         WebSettings webSettings = webView.getSettings();  
  29.         webSettings.setJavaScriptEnabled(true);  
  30.         webView.loadUrl("file:///data/js.html");  
  31.   
  32.         /***
  33.          *webChromeClient是一个比较神奇的东西,其里面提供了一系列的方法,
  34.          *分别作用于我们的javascript代码调用特定方法时执行,我们一般在其内部
  35.          *将javascript形式的展示切换为android的形式。  
  36.          * 例如:我们重写了onJsAlert方法,那么当页面中需要弹出alert窗口时,便
  37.          * 会执行我们的代码,按照我们的Toast的形式提示用户。
  38.          */  
  39.         class MyWebChromeClient extends WebChromeClient {  
  40.   
  41.             @Override  
  42.             public boolean onJsAlert(WebView view, String url, String message,  
  43.                     JsResult result) {  
  44.                 Toast.makeText(getApplicationContext(), message,  
  45.                         Toast.LENGTH_LONG).show();  
  46.                 return true;  
  47.             }  
  48.   
  49.         }  
  50.   
  51.         webView.setWebChromeClient(new MyWebChromeClient());  
  52.         /*
  53.          * 为javascript提供一个回调的接口,这里要注意,一定要在单独的线程中实现,要不会阻塞线程的
  54.          * addJavascriptInterface(Object obj, String interfaceName)
  55.          * obj代表一个java对象,这里我们一般会实现一个自己的类,类里面提供我们要提供给javascript访问的方法
  56.          * interfaceName则是访问我们在obj中声明的方法时候所用到的js对象,调用模式为window.interfaceName.方法名()
  57.          */  
  58.         webView.addJavascriptInterface(new Object() {  
  59.   
  60.             public void show() {  
  61.                 handler.post(new Runnable() {  
  62.                     @Override  
  63.                     public void run() {  
  64.                         Log.i("通知", "调用了该方法哦");  
  65.                         /*
  66.                          * 通过webView.loadUrl("javascript:xxx")方式就可以调用当前网页中的名称
  67.                          * 为xxx的javascript方法
  68.                          */  
  69.                         webView.loadUrl("javascript:show()");  
  70.                     }  
  71.                 });  
  72.   
  73.             }  
  74.   
  75.         }, "chenzheng_java");  
  76.   
  77.     }  
  78. }  

注意:
1)为了让WebView从apk文件中加载assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的assets目录中找内容。如上面的"file:///android_asset/demo.html"
2)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用Handler的目的。
3)如果你要访问网络,请在androidManifest.xml中加上权限<uses-permission android:name="android.permission.INTERNET"></uses-permission>
---------------------------------------------------------------------------------------------------------
我们在程序中可以看到,android访问网页以及与javascript交互主要用到了这么几个类:
WebView :我们可以认为它就是一个浏览器,会对用户访问的网址进行解析,下载,渲染……,然后返回给用户一个网页。  其内部使用的是webkit渲染引擎,它还包含了一些我们经常使用的功能,比如放大、缩小网页(需要在webSetting中先设置WebSettings.setBuiltInZoomControls(boolean));前进、后退……。
      默认情况下,webView对javascript和页面的错误都是忽略的。很多时候,如果我们想要加载一个uri,可能我们更多的会使用这种形式:
[java:nogutter] view plaincopy


  1. Uri uri = Uri.parse("http://www.example.com"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent);   

api中为我们提供了一个通过webView加载页面的例子,

我们可以看到,主要有loadUrl()和loadData()方法。这里请注意各个参数的含义哦、
-------------------------------------------------------------
此外,android还为我们提供了一些类来辅助我们的webview的使用。
WebViewClient:
。WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括:
 
  onLoadResource:通知webView加载url指定的资源时触发
  onPageStart:页面开始加载时触发
  onPageFinish:页面加载完毕时触发
  onReceiveError:出现错误时触发
  WebChromeClient:
WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等
   onCloseWindow(关闭WebView)
  onCreateWindow()
  onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)
  onJsPrompt
  onJsConfirm
  onProgressChanged
  onReceivedIcon
  onReceivedTitle
api中提供给我们一个实例:

WebSetting:和WebView是一一绑定的,控制webview的一些基础设置信息,如是否识别javascript,网页是否可放大缩小等。
--------------------------------------------------------------------------
如果我们想通过webview进行历史网页查看时,一定要注意,先通过如下方法判断下是否可执行该操作才好:

然后就可通过
voidgoBack()
Go back in the history of this WebView.
voidgoBackOrForward(int steps)
Go to the history item that is the number of steps away from the current item.
voidgoForward()
Go forward in the history of this WebView.
三个方法进行操作了,其中goBackOrForward传递进负数时为back操作,正数为forward操作。

你可能感兴趣的:(android)