webview介绍
在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件,用于浏览网页
混合编程:安卓程序没法跨平台,web(H5)性能,体验各方面跟不上,一个app中对性能要求比较高的部分会用原生代码来写,某些对性能要求没那么高的部分用h5来写。
webview的基本使用
-
加载本地图片
webView.loadUrl(“file:///sdcard/eee.jpg”); -
加载图片资源
mwvTest.loadUrl(“file:///android_asset/bbb.jpg”); -
加载含有视频播放功能的本地网页
mwvTest.loadUrl(“file:///sdcard/download/test.html”);
网页内容:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type"content="text/html; charset=gb2312"/>
</head>
<body>
<p>
<video src="/sdcard/download/splash.mp4"width="320"height="240"controls autoplay loop>
<source type=video/mp4 />
Your browser does not support the video tag.
</video>
</p>
</body>
</html>
需要设置webchromeclient:
mwvTest.setWebChromeClient(newWebChromeClient());
切换到后台:
@Override
protected void onPause() {
super.onPause();
mwvTest.onPause();
}
- 加载gif动图资源
mwvTest.loadUrl(“file:///android_asset/boy.jpg”);
加载网页
webView.loadUrl(“https://www.baidu.com”);
加载网页方法只能在主线程中访问,它本身是异步执行的
- 设置webviewclient
WebViewClient就是帮助WebView处理各种通知、请求事件的
设置webviewclient后,网页会在app中的webview加载,而不会调用系统浏览器加载,如果没有设置,会调用系统浏览器加载
点击网页中的链接,会出现加载不全的情况,因为没有允许js
webView.setWebViewClient(new WebViewClient());
- 设置允许js
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
- 不加载图片
mwvTest.getSettings().setBlockNetworkImage(true);
- 重写webviewclient中的shouldOverrideUrlLoading方法
这个方法在点击已加载网页中的子链接时回调,如果我们需要在点击某个链接时做一些事情,可以重写这个方法,比如点击一个网页连接跳转到一个activity中
如果此方法return true,表示已经处理完了点击请求,webview不会再做任何处理,如果return false(父类的这个方法默认就是return false,表示webview还会继续处理此请求),比如下面第一段程序,点击百度主页的图片子页链接,只会弹出toast,不会加载图片页面,点击其他子页链接,什么反应都没有,第二段程序中,点击百度主页的图片子页链接,会弹出toast,并加载网页,点击其他地方,不会弹出toast,会加载网页
@Override
public boolean shouldOverrideUrlLoading(WebView view,String url) {
editText.setText(url);
if (url.contains("image.baidu.com")){
Toast.makeText(MainActivity.this,"image",Toast.LENGTH_SHORT).show();
}
return true;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view,String url) {
editText.setText(url);
if (url.contains("image.baidu.com")){
Toast.makeText(MainActivity.this,"image",Toast.LENGTH_SHORT).show();
}
return false;
}
开始加载和加载完成的回调
public void onPageStarted(WebView view,String url,Bitmap favicon)
public void onPageFinished(WebView view,String url)
按回退键,可以使webview返回上一页
重写onkeydown方法,判断是否按下了返回键
如果按下了返回键,webview可以返回则返回上一页,并且return true,如果不可以返回,则调用父类的默认处理
按下其他键,还是调用父类的默认处理
@Override
public boolean onKeyDown(intkeyCode,KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK){
if (webView.canGoBack()){
webView.goBack();
return true;
}
}
return super.onKeyDown(keyCode,event);
}
- 设置WebChromeClient,并监控网页加载进度
重写WebChromeClient的onProgressChanged方法,此方法在加载进度改变时回调
WebChromeClient辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等
webView.setWebChromeClient(newWebChromeClient() {
@Override
public void onProgressChanged(WebView view, intnewProgress) {
}
});
public void onReceivedTitle(WebView view,String title)
- 设置网页自适应屏幕
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
webview中js和安卓原生的交互
- 可以用java调用js代码,也可以js代码调用java
- javascrip是一种脚本语言,他以对象的形式操作各种网页对象,比如window,document等
在android中定义一个类,其中的方法提供给js调用,方法前面要加上注解,否则会因为安全限制无法调用,如果是UI操作,需要发给UI线程执行
class JsTest{
@JavascriptInterface
public StringsayHello() {
return "Hello from android";
}
@JavascriptInterface
public void showAndroidButton(){
runOnUiThread(newRunnable() {
@Override
public void run() {
btGo.setVisibility(View.VISIBLE);
}
});
}
}
在asserts目录中新建一个html文件,代码如下:
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0032)http://localhost:8080/jsandroid/ -->
<html xmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
<meta http-equiv="Expires"content="0">
<meta http-equiv="Pragma"content="no-cache">
<meta http-equiv="Cache-Control"content="no-store,no-cache">
<meta name="Handheldfriendly"content="true">
<meta name="viewport"content="width=100%; initial-scale=1.0; user-scalable=yes">
<meta name="robots"content="all">
<meta name="keywords"contect="doodle, mobile, doodlemobile, game, games">
<meta name="description"content="Make People's Mobile Life More Connected Through Games.">
<title>jsandroid_test</title>
<script type="text/javascript"language="javascript">
function sayHello(){
var str = window.jsObj.sayHello();
alert(str);
}
function showAndroidButton(){
window.jsObj.showAndroidButton();
}
function showFromHtml( param ){
document.getElementById("id_input").value = "Java call Html : " + param;
}
</script>
</head>
<body>
hello IT-homer
<br>
<br>
<br>
<input type="button"value="sayHello"onclick="sayHello()"/>
<br>
<br>
<br>
<input type="button"value="showAndroidButton"onclick="showAndroidButton()"/>
<br>
<br>
<br>
<input type="button"value="excuteHtmlFun"onclick="window.jsObj.excuteHtmlFun()"/>
<br>
<br>
<br>
<input id="id_input"style="width: 90%"type="text"value="null"/>
</body>
</html>
把安卓中JsTest的对象关联为js中window下面的对象jsObj:
webView.addJavascriptInterface(newJsTest(),“jsObj”);
安卓中java代码也可以调用js代码,在test中增加一个方法:
@JavascriptInterface
public void excuteHtmlFun(){
runOnUiThread(new Runnable() {
@Override
public void run() {
webView.loadUrl("javascript: showFromHtml('1514')");
}
});
}
调用本地html文件:
String strUrl = "file:///android_asset/test.html";
webView.loadUrl(strUrl);
editText.setText(strUrl);
在弹出js alert对话框时可以回调,并替换默认的对话框,setWebChromeClient中调用:
@Override
public boolean onJsAlert(WebView view,String url,String message,JsResult result) {
new AlertDialog.Builder(MainActivity.this).setTitle("测试").setMessage(message).
setPositiveButton("ok", newDialogInterface.OnClickListener() {
@Override
public voidonClick(DialogInterface dialog, intwhich) {
}
}).create().show();
result.confirm();
return true;
}