1、WebView中JavaScript調(diào)用Android程序中Java:
使用WebView類中的addJavascriptInterface()方法,可以使用它擴(kuò)展嵌入式瀏覽器內(nèi)的DOM(文檔對象模型),并定義JavaScript代碼可以訪問的新對象。JavaScript代碼調(diào)用該對象的方法時(shí),實(shí)際上它會(huì)調(diào)用Android程序中的方法。
2、在Android程序中調(diào)用JavaScript方法:
調(diào)用loadUrl()方法,將URL以javascript:*要執(zhí)行的代碼 *的形式傳遞給它。瀏覽器會(huì)在當(dāng)前頁面執(zhí)行給定的JavaScript表達(dá)式,而不是轉(zhuǎn)到新的頁面。
實(shí)例:
構(gòu)建一個(gè)Android程序,布局如下(res/layout/activity_local_browser.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<WebView
android:id="@+id/web_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:orientation="vertical" >
<TextView
android:id="@+id/url_field"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/textview"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/call_javascript_from_android" />
<TextView
android:id="@+id/text_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
可以看出,布局的上半部分是WeView控件,下部分是來自Android用戶界面的TextView和Button。
下面需要完成將被加載到WebView中的index.html文件(assets/index.html),代碼如下
<html>
<head>
<script language="JavaScript">
function callJS(arg){
document.getElementById('replaceme').innerHTML = arg;
}
</script>
</head>
<body>
<h1>WebView</h1>
<p>
<a href="#" onclick="window.alert('Alert from JavaScript')">
Display JavaScript alert</a>
</p>
<p>
<a href="#" onclick="window.android.callAndroid('Hello from Browser')">
Call Android from JavaScript</a>
</p>
<p id="replaceme">
</p>
</body>
</html>
可以看到,callJS()函數(shù)是將會(huì)在Java代碼中被調(diào)用JavaScript函數(shù),它接收一個(gè)參數(shù)并賦值給replaceme標(biāo)簽。往下的兩條鏈接分別是調(diào)用window.alert()函數(shù)(顯示短消息)和window.android對象的callAndroid()方法(在Java代碼中定義好的)。
同時(shí)不要忘記在res/values/strings.xml文件中完成字符串的賦值:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">LocalBrower</string>
<string name="action_settings">Settings</string>
<string name="textview">TextView</string>
<string name="call_javascript_from_android">Call JavaScript from Android</string>
</resources>
完成這些準(zhǔn)備后,就可以把目光放在程序的LocalBrowser類上了,代碼如下:
package com.example.localbrowser;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.JavascriptInterface;
import android.webkit.JsResult;
import android.webkit.WebView;
import android.webkit.WebChromeClient;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
@SuppressLint("JavascriptInterface")
public class LocalBrowser extends ActionBarActivity {
private WebView webview;
private Button button;
private TextView textview;
private final Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_local_browser);
webview = (WebView) findViewById(R.id.web_view);
button = (Button) findViewById(R.id.button);
textview = (TextView) findViewById(R.id.text_view);
button.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
//單擊按鈕時(shí),通過WebView.loadUrl()方法調(diào)用index.html中定義的callJS()函數(shù)
webview.loadUrl("javascript:callJS('Hello from Android')");
}
});
//打開JavaScript(默認(rèn)是關(guān)閉的)
webview.getSettings().setJavaScriptEnabled(true);
//往WebView中注入Java對象,從而使得在index.tml中能使用此對象的方法
webview.addJavascriptInterface(new AndroidBridge(), "android");
webview.setWebChromeClient(new WebChromeClient() {
// 覆蓋默認(rèn)的window.alert()的展示界面
public boolean onJsAlert(final WebView view, final String url,
final String message, JsResult result) {
Toast.makeText(LocalBrowser.this, message, 3000).show();
result.confirm();
return true;
}
});
webview.loadUrl("file:///android_asset/index.html");//加載本地網(wǎng)頁,注意有3個(gè)斜杠
}
public class AndroidBridge {
@JavascriptInterface
// 要通過JavaScript調(diào)用的Java代碼片段
public void callAndroid(final String arg) {
handler.post(new Runnable() {
public void run() {
textview.setText(arg);
}
});
}
}
}
整個(gè)過程很簡單,但有點(diǎn)要注意的是:
在AdroidBridge類中
4.2之前向WebView注入的對象所暴露的接口callAndroid沒有注釋語句@JavascriptInterface,而4.2及以后的則多了注釋語句@JavascriptInterface。如果去掉這行代碼,當(dāng)程序調(diào)用此方法時(shí),將不能成功,而logcat會(huì)報(bào)如下輸出:
E/Web Console: Uncaught TypeError: Object [object Object] has no method 'callAndroid'
程序界面:
當(dāng)單擊按鈕和鏈接時(shí),它會(huì)在兩個(gè)環(huán)境間進(jìn)行調(diào)用,下面是運(yùn)行效果圖
更多建議: