Android的webview和JavaScript互相调用
Android中自定义文件必须放在资产文件夹下asset
1.用WebView来显示HTML代码
2.允许WebView执行JavaScript
webView.getSettings().setJavaScriptEnabled(true);
3.获取到HTML文件,也可从网络中获取
webView.loadUrl("file:///android_asset/test.html"); //HTML文件存放在assets文件夹中
4.使用addJavascriptInterface添加一个android中的某个类的对象, 让JS可以访问该对象的方法, 该对象中也可以调用JS中的方法
webView.addJavascriptInterface(new Contact(), "contact");
1 import android.app.Activity; 2 import android.content.Intent; 3 import android.net.Uri; 4 import android.os.Bundle; 5 import android.webkit.WebView; 6 7 public class MainActivity extends Activity { 8 private WebView webView; 9 10 public void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.main); 13 //加载页面 14 webView = (WebView) findViewById(R.id.webView); 15 //允许在webview执行JavaScript脚本 16 webView.getSettings().setJavaScriptEnabled(true); 17 //找到Html文件,也可以用网络上的地址 18 webView.loadUrl("file:///android_asset/index.html"); 19 // 使用addJavascriptInterface方法去添加一个android的类的对象, 让JS可以访问该对象的方法, 该对象中可以调用JS中的方法 20 webView.addJavascriptInterface(new Contact(), "contact"); 21 } 22 23 private final class Contact { 24 //JavaScript调用此方法拨打电话 25 public void call(String phone) { 26 startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone))); 27 } 28 29 //Html调用此方法传递数据 30 public void showcontacts() { 31 String json = "[{\"name\":\"zsw\", \"price\":\"16888888888\", \"phone\":\"1008610086\"}]"; 32 // 调用JS中的方法 33 webView.loadUrl("javascript:show(‘" + json + "‘)"); 34 } 35 } 36 }
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function show(jsondata){
var jsonobjs = eval(jsondata);
var table = document.getElementById("personTable");
for(var y=0; y<jsonobjs.length; y++){
var tr = table.insertRow(table.rows.length);
var td1 = tr.insertCell(0);
var td2 = tr.insertCell(1);
td2.align = "center";
var td3 = tr.insertCell(2);
td3.align = "center";
td1.innerHTML = jsonobjs[y].name;
td2.innerHTML = jsonobjs[y].price;
td3.innerHTML = "<a href=‘javascript:contact.call(\""+ jsonobjs[y].phone+ "\")‘>"+ jsonobjs[y].phone+ "</a>";
}
}
</script>
</head>
<body onload="javascript:contact.showcontacts()">
<table border="0" width="100%" id="personTable" cellspacing="0">
<tr>
<td width="30%">姓名</td>
<td width="30%" align="center">存款</td>
<td align="center">电话</td>
</tr>
</table>
</body>
</html>
拨打电话需要添加权限:
<uses-permission android:name="android.permission.CALL_PHONE" />
1 自定义webviewClient 2 @Override 3 public boolean shouldOverrideUrlLoading(WebView view, String url) { 4 5 //关于这点必须加入,否则自己的webview不能继续深入跳转页面层级 6 view.loadUrl(url); 7 return true; 8 } 9 10 11 public class MyWebClient extends WebViewClient 12 { 13 @Override 14 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) 15 { 16 Log.log_d("tweb", "onReceivedError errcode: " + errorCode + " description: " 17 + description + " failingUrl: " + failingUrl); 18 } 19 20 @Override 21 public boolean shouldOverrideUrlLoading(WebView view, String url) { 22 if (url.contains("tel:")) { 23 Intent myIntentDial = new Intent("android.intent.action.DIAL", 24 Uri.parse(url)); 25 startActivity(myIntentDial); 26 } else if (url.contains("download")) { 27 Intent viewIntent = new Intent(Intent.ACTION_VIEW, 28 Uri.parse(url)); 29 startActivity(viewIntent); 30 } else { 31 mProgressBar.setProgress(0); 32 mProgressBar.setVisibility(View.VISIBLE); 33 view.loadUrl(url); 34 } 35 return true; 36 } @Override 37 public void onLoadResource(WebView view, String url) 38 { 39 Log.log_d("tweb", "onLoadResource: " + url); 40 } 41 @Override 42 public void onPageStarted(WebView view, String url, Bitmap favicon) 43 { 44 Log.log_d("tweb", "onPageStarted: " + url); 45 if(url.equals(mHistoryTag)){ 46 mWebView.loadDataWithBaseURL(null, mDataSource, "text/html", "UTF-8", mHistoryTag); 47 } 48 mCurrentUrl = url; 49 50 } 51 52 @Override 53 public void onPageFinished(WebView view, String url) 54 { 55 Log.log_d("tweb", "onPageFinished: " + url); 56 } 57 @Override 58 public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError error) { 59 // 重写此方法可以让webview处理https请求 60 handler.proceed(); 61 } 62 } 63
下面摘自其他高手大大的:
在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件。
什么是webkit
WebKit是Mac OS X v10.3及以上版本所包含的软件框架(对v10.2.7及以上版本也可通过软件更新获取)。 同时,WebKit也是Mac OS X的Safari网页浏览器的基础。WebKit是一个开源项目,主要由KDE的KHTML修改而来并且包含了一些来自苹果公司的一些组件。
传统上,WebKit包含一个网页引擎WebCore和一个脚本引擎JavaScriptCore,它们分别对应的是KDE的KHTML和KJS。不过, 随着JavaScript引擎的独立性越来越强,现在WebKit和WebCore已经基本上混用不分(例如Google Chrome和Maxthon 3采用V8引擎,却仍然宣称自己是WebKit内核)。
这里我们初步体验一下在android是使用webview浏览网页,在SDK的Dev Guide中有一个WebView的简单例子 。
==========================================================================
1.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错误。
==========================================================================
2.如果访问的页面中有Javascript,则webview必须设置支持Javascript。
webview.getSettings().setJavaScriptEnabled(true);
3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象。
mWebView.setWebViewClient(new WebViewClient(){ public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });
4.如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。
public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); }
5.android中webview支持javascript自定义对象
a.设置webview支持javascript. webSettings.setJavaScriptEnabled(true);
b.绑定android对象到javascript对象. addJavascriptInterface(Object obj,String interfaceName);
c.页面中调用javascript对象. javascript:window.demo.方法名称();
在w3c标准中js有 window,history,document等标准对象,同样我们可以在开发浏览器时自己定义我们的对象调用手机系统功能来处理,这样使用js就可以 为所欲为了。
看一个实例:
1 public class WebViewDemo extends Activity { p 2 rivate WebView mWebView; 3 private Handler mHandler = new Handler(); 4 public void onCreate(Bundle icicle) { 5 super.onCreate(icicle); 6 setContentView(R.layout.webviewdemo); 7 mWebView = (WebView)findViewById(R.id.webview); 8 WebSettings webSettings = mWebView.getSettings(); 9 10 webSettings.setJavaScriptEnabled(true); 11 mWebView.addJavascriptInterface(new Object() { 12 public void clickOnAndroid() { 13 mHandler.post(new Runnable() 14 { public void run() { 15 mWebView.loadUrl("javascript:wave()"); } 16 }); } }, "demo"); 17 mWebView.loadUrl("file:///android_asset/demo.html"); } }
我们看addJavascriptInterface(Object obj,String interfaceName)这个方法,该方法将一个java对象绑定到一个javascript对象中,javascript对象名就是 interfaceName(demo),作用域是Global。这样初始化webview后,在webview加载的页面中就可以直接通过 javascript:window.demo访问到绑定的java对象了。
来看看在html中是怎样调用的。
<html>
<script language="javascript"><!--
function wave() {
document.getElementById("droid").src="android_waving.png";
}
// --></script>
<body>
<a onClick="window.demo.clickOnAndroid()">
<img id="droid" src="android_normal.png" src="android_normal.png"/><br>
Click me!
</a>
</body>
</html>
这样在javascript中就可以调用java对象的clickOnAndroid()方法了,同样我们可以在此对象中定义很多方法(比 如发短信,调用联系人列表等手机系统功能。),这里wave()方法是java中调用javascript的例子。
这里还有几个知识点:
1)为了让WebView从apk文件中加载assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的 assets目录中找内容。如上面的"file:///android_asset/demo.html"
2)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用 Handler的目的。
6.webview 中使用div层会出现重叠显现.
只能用dom方式操作div的删除动作.
7.android中webview接收favicon总是获取为null解决方案
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。