android + javascript 相互通信實例分析


 

1.  AndroidManifest.xml中必須使用許可 "android.permission.INTERNET", 否則會出Web page not available錯誤。

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

2.  如果訪問的頁面中有Javascript,則webview必須設置支持Javascript。

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

3.如果頁面中鏈接,如果希望點擊鏈接繼續在當前browser中響應,而不是新開Android的系統browser中響應該鏈接,必須覆蓋 webview的WebViewClient對象或者覆蓋webview的 setWebChromeClient

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對象

  對象注入即通過webview 建立 javascript對象 與 android 原生對象的綁定關系,下面代碼中,obj1對象在android程序中可以操作,obj2在js程序中可以操作,兩者操作的均為同一個內存對象,即可以理解為,兩個綁定的對象是同一個對象在不同運行環境下的一個別名(僅個人理解,有誤請大牛指正)

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>

 

 

 

參考文檔:

[1]. WebView注入Java對象注意事項     參考:http://blog.csdn.net/zgjxwl/article/details/9627685

[2]. Android WebView的Js對象注入漏洞解決方案  http://my.oschina.net/u/1402271/blog/306364

[3]. https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface

[4]. http://wenku.baidu.com/link?url=MLiRIwZQUc3-CAbSopUD-_OZ2Jt67K74RHDzqVJZCkDRnbkXp-66P9ArMbtNSy3LiPZ__nLxcQaoXP7ZImv7AujsFwBybB9wlbCJaGVTjD_

[5]. https://code.google.com/p/apps-for-android/source/browse/#git%2FSamples%2FWebViewDemo%253Fstate%253Dclosed

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM