做項目時候會遇到我們用WebView 打開一個web,希望這個web可以調用自己的一些方法,比如我們在進一個web頁面,然后當我們點擊web上的某個按鈕時,希望能判斷當前手機端是否已經登錄,如果未登錄,那么就會跳轉到登錄頁面(登陸頁面是另一個Activity)。這個時候,一個簡單的做法就是在按鈕動作事件的js上調用java的方法,從而起到判斷是否登錄,並決定是否跳轉到另一個頁面。
Google的WebView為我們提供了 addJavascriptInterface(Object obj, String interfaceName)方法,這個方法的第一個參數是傳給Web的對象,第二個參數是該對象的對象名。
寫個簡單的例子
public class WebActivity extends Activity{ ProgressBar mProgressBar; WebView mWebView; String mUrl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.web); mWebView = (WebView) findViewById(R.id.web_view); mProgressBar = (ProgressBar) findViewById(R.id.loading_progress); doWebViewSetting(); // 加載網頁 loadUrl("http://172.10.1.2:8080/test"); } private void doWebViewSetting(){ // 設置WebClient(可不要) mWebView.setWebViewClient(new MyWebViewClient()); // 支持js(必要) mWebView.getSettings().setJavaScriptEnabled(true); // 添加js對象(必要) mWebView.addJavascriptInterface(new JsOperation(this), "client"); } private void loadUrl(String url) { mUrl = url; mProgressBar.setVisibility(View.VISIBLE); mWebView.loadUrl(url); } class MyWebViewClient extends WebViewClient{ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); mProgressBar.setVisibility(View.GONE); } } class JsOperation { Activity mActivity; public JsOperation(Activity activity) { mActivity = activity; } // 測試方法
@javascriptInterface public void test() { Toast.makeText(mActivity,"test",Toast.LENGTH_SHORT).show(); } }
以上是我的WebActivity ,我這里只簡單的實現的加載時進度條顯示和提供對象給js。可以看出,我們提供了一個JsOperation 對象給web,然后在JsOperation 類中定義了test()方法。接下來就看看,Web方面要如何調用該方法。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>測試</title> <script type="text/javascript"> function test(){ client.test() } </script> </head> <body> <br /> <button onclick="test()">test</button> </body> </html>
web的實現方式特別簡單,直接調用我們提供的對象,這里要注意的是,對象名是我們之前傳入的String,這里是client,直接調用它的test()方法,就能彈出一個Toast了,當然你也可以在這個方法里做其他的各種處理,也可以提供多個方法,如果你需要傳入參數,那么在java上定義好形參后,js上就正常的調用方法並傳入參數,如client.test(param)就可以了,沒什么特別要注意的地方。
特別注意:Android的WebView存在安全漏洞,因為js調用對象是可以通過反射再調用Runtime甚至可能以web掛馬形式控制主機,google也承認webView這個功能太強了,給了web很大的權利,Android 4.2 (api17)已經開始采用新的接口方法,@JavascriptInterface 代替addjavascriptInterface, 但是低版本上是不能避免。
