Android WebView與JavaScript交互操作(Demo)
應用場景:
? ? ? ?為了使Android移動項目能夠在較短的時間內完畢開發。同一時候減少技術人員開發的成本投入。往往會採用Hybrid APP的開發模式。相關Hybrid APP(混合型應用)參看:http://blog.csdn.net/mahoking/article/details/30235243 採用這種模式,為了解決更好的用戶體驗。可訪問本地資源的能力。勢必須要了解與掌握Android(java)與JavaScript之間的交互、相互調用操作的方法與技術。
【轉載使用。請註明出處:http://blog.csdn.net/mahoking/article/details/32707013】
知識點介紹:
? ? ? ??本文重要的知識點補充是WebView對象(android.webkit.WebView)。在Android手機中內置了一款高性能webkit內核瀏覽器。在Android SDK中封裝為一個叫做WebView組件。
?
? ? ? ? WebKit是Mac OS X v10.3及以上版本號所包括的軟件框架(對v10.2.7及以上版本號也可通過軟件更新獲取)。 同一時候。WebKit也是Mac OS X的Safari網頁瀏覽器的基礎。WebKit是一個開源項目。主要由KDE的KHTML改動而來而且包括了一些來自蘋果公司的一些組件。?
【註意事項】
1.AndroidManifest.xml中必須使用許可"android.permission.INTERNET",否則會出Web page not available錯誤。
2.假設訪問的頁面中有Javascript。則webview必須設置支持Javascript。webview.getSettings().setJavaScriptEnabled(true); ?
4.對於第一點, 假設使用Android SDK提供了一個schema,前綴為"file:///android_asset/"。WebView遇到這種schema。會去載入assets文件夾下的資源。
如"file:///android_asset/demo.html"。可不必使用許可"android.permission.INTERNET"。
? ? ? ? 在使用WebView組件的過程中可能會接觸到WebViewClient與WebChromeClient,那麽這兩個類究竟有什麽不同呢?
? ? ? ? ?WebViewClient主要幫助WebView處理各種通知、請求事件的。比方:
- onLoadResource
- onPageStart
- onPageFinish
- onReceiveError 等
- onCloseWindow(關閉WebView)
- onCreateWindow()
- onJsAlert (WebView上alert無效,須要定制WebChromeClient處理彈出)
- onJsPrompt
- onJsConfirm
- onReceivedTitle等
【轉載使用,請註明出處:http://blog.csdn.net/mahoking/article/details/32707013】
使用方式:
第一步: 本文的演示程序的主界面為activity_web.xml,相應的Activtiy為WebActivtiy.java。【activity_web.xml】
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
tools:context=".WebActivity" >
<LinearLayout android:layout_height="wrap_content"
android:background="@drawable/bgcolorblue"
android:id="@+id/top_layout"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:orientation="horizontal">
<Button android:layout_height="wrap_content"
android:background="@drawable/titlebackground"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="match_parent"
android:id="@+id/javaCallJs_web_button"
android:text="Java調用無參數JS"/>
<Button android:layout_height="wrap_content"
android:background="@drawable/titlebackground"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="match_parent"
android:id="@+id/javaCallJsParam_web_button"
android:text="Java調用含參數JS"/>
</LinearLayout>
<WebView
android:layout_below="@id/top_layout"
android:id="@+id/webView_web"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
【WebActivtiy.java】
package cn.mahaochen.webviewtest;
import cn.mahaochen.webviewtest.assist.ButtonListener;
import cn.mahaochen.webviewtest.assist.MJavascriptInterface;
import cn.mahaochen.webviewtest.assist.MWebChromeClient;
import cn.mahaochen.webviewtest.assist.MWebViewClient;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.KeyEvent;
import android.view.Menu;
import android.webkit.WebView;
import android.widget.Button;
/**
* @date 2014-6-20
* @author MaHaochen
*/
public class WebActivity extends Activity {
private WebView webView;
private Button paramButton;
private Button noParamButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
initViews();
}
private void initViews() {
webView = (WebView) findViewById(R.id.webView_web);
// 設置WebView對JavaScript的支持
webView.getSettings().setJavaScriptEnabled(true);
// 從assets文件夾以下的載入html
webView.loadUrl("file:///android_asset/web.html");
//自己定義WebView的背景顏色
webView.setBackgroundColor(Color.TRANSPARENT);//先設置背景色為transparent
// webView.setBackgroundResource(R.drawable.webbg);//然後設置背景圖片
webView.setBackgroundResource(R.drawable.bgcolorblue);
// webView.loadUrl("http://www.baidu.com");
MWebViewClient mWebViewClient = new MWebViewClient(webView,getApplicationContext());
webView.setWebViewClient(mWebViewClient);
MWebChromeClient mWebChromeClient = new MWebChromeClient(getApplicationContext());
webView.setWebChromeClient(mWebChromeClient);
//加入JS調用Android(Java)的方法接口
MJavascriptInterface mJavascriptInterface = new MJavascriptInterface(getApplicationContext());
webView.addJavascriptInterface(mJavascriptInterface, "WebViewFunc");
//初始化按鈕,並綁定監聽事件。事件的作用是調用JS的功能方法
noParamButton = (Button) findViewById(R.id.javaCallJs_web_button);
paramButton = (Button) findViewById(R.id.javaCallJsParam_web_button);
ButtonListener buttonListener = new ButtonListener(webView);
noParamButton.setOnClickListener(buttonListener);
paramButton.setOnClickListener(buttonListener);
}
/**
* 退出監聽
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0
) {
if(webView.canGoBack()){
webView.goBack();
return false;
}else {
WebActivity.this.finish();
return true;
}
}
return false;
// return super.dispatchKeyEvent(event);
}
//*******************華麗的切割線***********************
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// getMenuInflater().inflate(R.menu.web, menu);
return true;
}
}
第二步: ? ? ? ? 從第一步能夠看到,以上補充了分別繼承自WebViewClient、WebChromeClient的MWebViewClient、MWebChromeClient對象和MJavascriptInterface、ButtonListener對象。相應的對象的相關方法與操作的介紹將會在代碼中較具體的敘述。
【MWebViewClient.java】
package cn.mahaochen.webviewtest.assist;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.util.Log;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
/**
* @date 2014-6-20
* @author MaHaochen
*/
public class MWebViewClient extends WebViewClient {
private WebView webView;
private Context context;
public MWebViewClient(WebView webView) {
super();
this.webView = webView;
}
public MWebViewClient(WebView webView, Context context) {
super();
this.webView = webView;
this.context = context;
}
/**
* 在點擊請求的是鏈接是才會調用,
* 重寫此方法返回true表明點擊網頁裏面的鏈接還是在當前的webview裏跳轉,不跳到瀏覽器那邊。
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 使用自己的WebView組件來響應Url載入事件。而不是使用默認瀏覽器器載入頁面
webView.loadUrl(url);
// 記得消耗掉這個事件。給不知道的朋友再解釋一下。Android中返回True的意思就是到此為止,
// 事件就會不會冒泡傳遞了,我們稱之為消耗掉
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// Toast.makeText(context, "WebViewClient.onPageStarted頁面開始載入", Toast.LENGTH_SHORT).show();
Log.e("WebActivity", "頁面載入開始");
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
// Toast.makeText(context, "WebViewClient.onPageFinished頁面載入完畢", Toast.LENGTH_SHORT).show();
Log.e("WebActivity", "頁面載入完畢");
super.onPageFinished(view, url);
}
/**
* 在載入頁面資源時會調用,每個資源(比方圖片)的載入都會調用一次。
*/
@Override
public void onLoadResource(WebView view, String url) {
// Toast.makeText(context, "WebViewClient.onLoadResource", Toast.LENGTH_SHORT).show();
Log.e("WebActivity", "onLoadResource");
super.onLoadResource(view, url);
}
/**
* 重寫此方法能夠讓webview處理https請求 [拓展]
*/
@Override
public void onReceivedSslError(WebView view,
SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
}
}
【MWebChromeClient.java】
package cn.mahaochen.webviewtest.assist;
import android.app.Activity;
import android.content.Context;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
/**
* @date 2014-6-20
* @author MaHaochen
*/
public class MWebChromeClient extends WebChromeClient {
private Context context;
public MWebChromeClient(Context context) {
super();
this.context = context;
}
// 處理Alert事件
@Override
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
return super.onJsAlert(view, url, message, result);
}
// onReceivedTitle()方法改動網頁標題
@Override
public void onReceivedTitle(WebView view, String title) {
((Activity)context).setTitle("能夠用onReceivedTitle()方法改動網頁標題");
super.onReceivedTitle(view, title);
}
// 處理Confirm事件
@Override
public boolean onJsConfirm(WebView view, String url, String message,
JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
// 處理提示事件
@Override
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, JsPromptResult result) {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
}
【MJavascriptInterface.java】
package cn.mahaochen.webviewtest.assist;
import android.content.Context;
import android.widget.Toast;
/**
* @date 2014-6-20
* @author MaHaochen
*/
public class MJavascriptInterface {
private Context context;
public MJavascriptInterface(Context context) {
super();
this.context = context;
}
/**
* JS調用Android(Java)無參數的方法
*/
public void jsCallWebView() {
Toast.makeText(context, "JS Call Java!",
Toast.LENGTH_SHORT).show();
}
/**
* JS調用Android(Java)含參數的方法
* @param param
*/
public void jsCallWebView(String param) {
Toast.makeText(context, "JS Call Java!" + param,
Toast.LENGTH_SHORT).show();
}
}
【ButtonListener.java】
package cn.mahaochen.webviewtest.assist;
import cn.mahaochen.webviewtest.R;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
/**
* @date 2014-6-20
* @author MaHaochen
*/
public class ButtonListener implements OnClickListener{
private WebView webView;
public ButtonListener(WebView webView) {
super();
this.webView = webView;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.javaCallJs_web_button:
webView.loadUrl("javascript:javacalljs()"); // 無參數調用
break;
case R.id.javaCallJsParam_web_button:
webView.loadUrl("javascript:javacalljsparam(" + "‘含參數‘"+ ")"); // 無參數調用
break;
default:
break;
}
}
}
第三步: ? ? ? ? 以上是所有的Java代碼部分的信息。本例旨為演示WebView(Java)與JS(JavaScript)的互操作。
所以須要補充另兩個資源文件web.html與jump.html頁面。該頁面位於項目的assets文件夾下。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK"/>
<script type="text/javascript">
//Java調用JS代碼無參數
function javacalljs(){
document.getElementById("content").innerHTML +=
"<br\>java調用了js函數";
}
//Java調用JS代碼有參數
function javacalljsparam(param){
document.getElementById("content").innerHTML +=
"<br\>java調用了js函數含參數param"+param;
}
function testFunc(){
window.WebViewFunc.jsCallWebView();
}
</script>
<title>測試頁面</title>
</head>
<body>
<a onClick="testFunc()">無參數JS調用java代碼</a><br/>
<a onClick="window.WebViewFunc.jsCallWebView(‘含有參數‘)">含參數調用java代碼</a><br/>
<br />
<div id="content">內容顯示 <a href="jump.html" target="_self">跳轉新頁面jump.html</a></div>
</body>
</html>
【jump.html】
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK"/>
<script type="text/javascript">
//Java調用JS代碼無參數
function javacalljs(){
document.getElementById("content").innerHTML +=
"<br\>java調用了js函數";
}
//Java調用JS代碼有參數
function javacalljsparam(param){
document.getElementById("content").innerHTML +=
"<br\>java調用了js函數含參數param"+param;
}
function testFunc(){
window.WebViewFunc.jsCallWebView();
}
</script>
<title>測試頁面</title>
</head>
<body>
<a onClick="testFunc()">無參數JS調用java代碼</a><br/>
<a onClick="window.WebViewFunc.jsCallWebView(‘含有參數‘)">含參數調用java代碼</a><br/>
<br />
<div id="content">內容顯示</div>
</body>
</html>
■註:因為本演示案例加入必要的圖片文件與樣式文件。才幹夠出現以下效果截圖,所以假設獲取完整的效果,請在【下載地址】欄。自行下載完整項目。
效果截圖:
下載地址:
http://download.csdn.net/detail/ma_hoking/7525549? ?點擊下載參考文獻:
1、 http://www.cnblogs.com/oakpip/archive/2011/04/08/2009800.html2、 http://blog.csdn.net/jackyhuangch/article/details/8310033
Android WebView與JavaScript交互操作(Demo)