android + javascript 相互通讯实例分析

关键点:
正向通信(js调用Android方法)
1.在Android程序中为WebView控件增长一个与JS的暗号,demo。如WebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
2.在Android程序中的定义一个支持js调用的方法,须要经过注解标志@JavascriptInterface。如 @JavascriptInterface public void clickOnAndroid() {}
3.在WebView打开的网页js中按照暗号要求,定义一个js方法,window.demo.clickOnAndroid()
以上3点完成js调用android的程序

逆向通信(android调用js方法)
1.在js定义一个方法,function wave(){}
2.在Android程序中调用js方法mWebView.loadUrl("javascript:wave()");

Android与js通信原理:
1.在Android中定义各类支持请求的监听服务和业务实现,用于接收到js请求,生成Android的Intent对象,而且广播出去,监听服务收到这个广播开始作事情
2.在Android中定义一个专门处理js请求的类,类中的方法须要经过@JavascriptInterface 注解标志(至关于用java代码写js代码)
3.把这个能够处理js请求的java类注册到Android中的WebView控件中,而且须要写一个实例名字(这个实例名字是与js的通讯约定)
4.在js中经过实例名称直接调用Android的方法javascript

 

实例分析:html

1.  AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 不然会出Web page not available错误。java

<uses-permission android:name="android.permission.INTERNET"/>

2.  若是访问的页面中有Javascript,则webview必须设置支持Javascript。android

1   WebSettings webSetting = webview.getSettings();
2   webSetting.setJavaScriptEnabled(true);

3.若是页面中连接,若是但愿点击连接继续在当前browser中响应,而不是新开Android的系统browser中响应该连接,必须覆盖 webview的WebViewClient对象或者覆盖webview的 setWebChromeClientweb

1 mWebView.setWebViewClient(new WebViewClient(){
2 public boolean shouldOverrideUrlLoading(WebView view, String url) { 
3     view.loadUrl(url); 
4     return true; 
5    }
6  });

 

复制代码

 1   mWebView.setWebChromeClient(new MyWebChromeClient()
 2             @Override
 3             public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
 4                 Log.d(LOG_TAG, message);
 5                 result.confirm();
 6                 return true;
7             });

复制代码

 

4.  若是不作任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,若是但愿浏览的网 页回退而不是推出浏览器,须要在当前Activity中处理并消费掉该Back事件。浏览器

复制代码

1 public boolean onKeyDown(int keyCode, KeyEvent event) { 
2   if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { 
3     mWebView.goBack(); 
4     return true; 
5   } 
6   return super.onKeyDown(keyCode, event); 
7 }

复制代码

 

 5.  javascript对象 与 android 对象绑定安全

WebView注入Java对象eclipse

  对象注入即经过webview 创建 javascript对象 与 android 原生对象的绑定关系,下面代码中,obj1对象在android程序中能够操做,obj2在js程序中能够操做,二者操做的均为同一个内存对象,便可以理解为,两个绑定的对象是同一个对象在不一样运行环境下的一个别名(仅我的理解,有误请大牛指正)ide

1 webview.getSetting().setJavaScriptEnable(true);  
2 class JsObject {  
3  @JavascriptInterface  4     public String toString() { return "injectedObject"; }  
5  }  
6  webView.addJavascriptInterface(new JsObject()obj1, "injectedObject"obj2);

  上面的程序创建 javascript 与android 程序的绑定关系,android 4.2 以后版本提供给js调用的函数必须带有注释语句@JavascriptInterface ,4.2版本以前向webview注入的对象所暴露的接口不是必须带有@JavascriptInterface注释语句(须要注意,android adt,eclipse生成的工程,低版本中会自动带有 anotations.jar,支持@JavascriptInterface, 而高版本中工程中,不会自动带有anotations.jar包,因此要加入注释语句@JavascriptInterface,首先要本身手动加入anotations.jar包,不要忘记import 哦!本人就犯过这么低级的错误哦)函数

   官方文档解释是由于这个接口容许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,由于JavaScript 能够使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会容许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。所以4.2之后,任何为JS暴露的接口,都须要加 @JavascriptInterface 注释,这样,这个Java对象的fields 将不容许被JS访问。[2] 

   注:若是将targetSdkVersion 设置为17或者更高,但却没有给暴露的js接口加@JavascriptInterface注释,则logcat会报以下输出:

   Console: Uncaught TypeError: Object [object Object] has no method 'toString'

  (须要特注意的一点,这里的限制是经过 targetSdkVersion 为标准,即若是工程采用了android sdk的版本是4.2以上,可是 targetSdkVersion 的版本在17之下,那么该状态下生成的应用,不过报错,若是targetSdkVersion 设置为>=17 就须要特别主意,要加上 @JavascriptInterface注释语句了, 全部建议在各类版本下都采用@JavascriptInterface注释,就万无一失了)

 

6.  在作webview开发是常常会加载本机的html文件以下:

 file:///android_asset/teste.html   加载项目assets下的文件teste.html

 file:///sdcard/index.html       加载sdcard下的index.html文件

 

源代码:

android

复制代码

 1      private WebView mWebView;
 2       private Handler mHandler = new Handler();
 3       
 4       @Override
 5       protected void onCreate(Bundle savedInstanceState) {
 6           super.onCreate(savedInstanceState);
 7          setContentView(R.layout.main);
 8          mWebView = (WebView) findViewById(R.id.webview);
 9 
10          WebSettings webSettings = mWebView.getSettings();
11          webSettings.setJavaScriptEnabled(true);
12          webSettings.setSavePassword(false);
13          webSettings.setSaveFormData(false);
14          webSettings.setSupportZoom(false);
15  
16          mWebView.setWebChromeClient(new MyWebChromeClient());
17          mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
18  //      mWebView.loadUrl("http://www.baidu.com/");
19          mWebView.loadUrl("file:///android_asset/demo.html");
20      }
21      
22       final class DemoJavaScriptInterface {
23              DemoJavaScriptInterface() {
24                  Log.i("aaaa", "create DemoJavaScriptInterface");
25              }
26              /**
27               * This is not called on the UI thread. Post a runnable to invoke
28               * loadUrl on the UI thread.
29               */
30         @JavascriptInterface 31              public void clickOnAndroid() {
32                 mHandler.post(new Runnable() {
33                     public void run() {
34                          mWebView.loadUrl("javascript:wave()");
35                      }
36                  });
37              }
38          }
39          /**
40          * Provides a hook for calling "alert" from javascript. Useful for
41           * debugging your javascript.
42           */
43         final class MyWebChromeClient extends WebChromeClient {
44             @Override
45              public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
46                 result.confirm();
47                 return true;
48             }
49         }

复制代码

 

html源文件

复制代码

 1 <!DOCTYPE html>
 2 <html>
 3     <script language="javascript">
 4         /* This function is invoked by the activity */
 5         function wave() {
 6             alert("1");
 7             document.getElementById("droid").src="android_waving.png";
 8             alert("2");
 9         }
10     </script>
11     <body>
12         <!-- Calls into the javascript interface for the activity -->
13         <a onClick="window.demo.clickOnAndroid()">
14         <div style="width:80px;
15             margin:0px auto;
16             padding:10px;
17             text-align:center;
18             border:2px solid #202020;" >
19                 <img id="droid" src="android_normal.png"/><br>
20                 Click me!
21         </div></a>
22     </body>
23 </html>

复制代码

相关文章
相关标签/搜索