原来你是这样的WebView
Posted SmallCheric
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原来你是这样的WebView相关的知识,希望对你有一定的参考价值。
随着html5的快速发展,越来越多的App对WebView的使用越来越频繁,不再像以前一样只需要调用
webview.loadurl(url)
就可以满足基本的使用,本文就对目前WebView的常用用法进行总结介绍,希望能帮到一些小伙伴…
1. WebView是个什么鬼
一个用来展示web界面的View, WebView可以在自己的浏览器或者Activity中进行内容展示,采用了WebKit渲染引擎来显示网页,包括历史导航,前一页,后一页,放大,缩小,执行搜索文本等功能;如果你想在项目中使用WebView,需要添加一个访问网络的权限:
uses-permission android:name=”android.permission.INTERNET”
2. WebView的基本使用
2.1 发送Intent调用系统浏览器打开加载页
WebView在默认情况下,不支持浏览器中例如widget插件,默认关闭Js交互,并忽略网页上将被忽略;如果你只想展示一个页面,但是并不需要交互,那使用webview是比较合适的; 如果你想实现一个全面的web页面,那么你可以开启一个URL意图来使用浏览器打开当前URL,但一般为了用户体验,这种用法的使用还是比较少的;示例如下
Uri uri = Uri.parse("http://www.baidu.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
2.2 调用webview.loadUrl(url)来加载
2.2.1 webview.loadUrl(url)加载网络地址
当然,多数情况下,我们会在layout文件中定义一个webview控件,然后在Activity中的onCreate里面加载我们想要看到的url界面,使用如下:
//第一种写法,常用格式
WebView webView = (WebView) findViewById(R.id.webview);
webView.loadUrl("http://www.baidu.com");
//注意:如果不想弹出系统浏览器进行界面显示,需要重写该方法
webView.setWebViewClient(new WebViewClient()
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
view.loadUrl(url);
//返回值没有关系
return super.shouldOverrideUrlLoading(view,url);
);
//第二种写法,直接在setContentView中传入webview
WebView webView = new WebView(this);
webView.loadUrl("http://www.baidu.com");
setContentView(webView);
webView.setWebViewClient(new WebViewClient()
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
view.loadUrl(url);
//返回值没有关系
return super.shouldOverrideUrlLoading(view,url);
);
注意:如果不想弹出系统浏览器进行界面显示,需要重写shouldOverrideUrlLoading方法
2.2.2 webview.loadUrl(url)加载apk包内html文件
webview不但可以加载网络页面,也可以加载apk包下的html文件,将html文件放在项目assets资源目录下,然后调用以下代码即可
webView.loadUrl("file:///android_asset/test.html");
2.2.3 webview.loadUrl(url)加载SD卡下的html文件
webview加载SD卡根目录下test.html文件代码如下:
webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
2.3 webview加载HTML格式字符串
除了可以加载网页之外,webview也可以加载HTML格式的字符串;主要是两个方法,一个webView.loadData(data,mimeType,encoding);
来展示,一个是webView.loadDataWithBaseURL(baseUrl,data,mimeType,encoding,historyUrl);
. 如果是带有中文的数据,默认显示会展示乱码,可以有两种方式来解决乱码;我们先来看一下如果都是英文数据该如何展示:
String data = "<html><body>You scored <b>Egglish</b> points.</body></html>";
webView.loadData(summary, "text/html", null);
展示效果如图所示:
如果包含了中文,会显示乱码:
第一种修改方式,可以在loadData中更改第二个参数,注意:如果将第三个参数更改为”UTF-8”,依然会是乱码;正确修改如下:
String data = "<html><body>You scored <b>中文测试</b> points.</body></html>";
webView.loadData(data, "text/html; charset=UTF-8", null);
显示效果如下:
原因如下:
如果用
loadDataWithBaseURL
时,如果不传入URL时,刷新会造成白屏,因为刷新时调用的的是reload方法,reload是根据传入的URL进行一次重新加载即再次loadUrl(url),不传入URL时,默认的的URL是about:blank;使用loadData,刷新只是从缓存里面取,但是在4.0以上的,如果按照API里所写的loadData(data, “UTF-8”, null);
时会乱码,如果写成loadData(data, "text/html; charset=UTF-8", null);
loadData最终的机制是会把传入的三个参数拼接在一起,然后再进行loadUrl操作,参数就是data, "text/html; charset=UTF-8", null
这三个进行拼装,加入text/html; charset=UTF-8
就相当于限定了页面的字符
上面的一种修改方式可以适配大多数机型,但依然有少部分机型会显示乱码,可能与系统底层文件修改有关,所以就有了另一种修改方式,调用loadDataWithBaseURL方法,修改如下:
String data = "<html><body>You scored <b>中文测试</b> points.</body></html>";
webView.loadDataWithBaseURL(null,summary,"text/html","UTF-8",null);
3. 自定义你的webview
WebView除了基本的用法以外,还可以进行自定义来达到你想要的效果,比如创建一个匿名WebChromeClient来辅助WebView处理javascript的对话框,网站图标,网站title,加载进度等;也可以创建一个匿名WebViewClient ,来帮助WebView处理各种通知、请求事件等;当然,也可以启用 WebSettings,来开启Js交互等等,下面我们就来逐一介绍.
3.1 WebChromeClient
方法中的代码均有Android端自行处理,实现方式可以写一个匿名内部类,或者写一个WebChromeClient类,然后调用webview.setWebChromeClient(mWebChromeClient);代码示例如下:
webView.setWebChromeClient(new WebChromeClient()
//获取网页的加载进度,因有的网页是采用分模块加载,所以进度值并非只是一次1~100;可以为: 29~100;30~100;
@Override
public void onProgressChanged(WebView view, int progress)
Log.e(TAG,"progress="+progress);
//获取当前网页中的Title值来设置给自己的title
//注意:如果无网,获取的 title= 找不到网页
//所以开发者可以在接受到onReceiveError的回调后,不要在使用当前获取的title值了
@Override
public void onReceivedTitle(WebView view, String title)
Log.e(TAG,"title="+title);
//获取当前网页的icon,拿到后,会获取一个Bitmap对象,你想干嘛就干嘛
@Override
public void onReceivedIcon(WebView view, Bitmap icon)
super.onReceivedIcon(view, icon);
);
以上为简单用法,下面我们对 onJsAlert()
, onJsPrompt()
,onJsConfirm()
进行逐一分析;在WebChromeClient类里可以重写这三个方法,此时WebView中加载的html中如果执行alert("alert....");
, confirm("confirm...");
, prompt("prompt...", "defaultValue");
这三个方法,该类就会监听到执行对应的三个方法。我们可以让这三个方法的返回值为true ,即自定义此方法。在里面写入自己定义的Dialog,便可实现html与Activity交互。
注意 JsResult 此类需要在操作时,如果操作则 result.cofirm(). 取消则 result.cancel(); 还必须这每一个方法中写入 dialog.setOnkeyListener(); 方法来监听Back键,listener中 要写 result.cancel(); 否则系统没有消费这个事件,会出错。
3.1.1 自定义onJsAlert
什么是Javascript Alert?
Alert是一种提示信息或者警告信息的对话框,一旦显示到用户面前,只能点击OK才能关闭.
通常一般的实现类似:
<html>
<SCRIPT type="text/javascript">
alert('This is alert dialog !')
</SCRIPT>
</html>
效果图如下:
onJsAlert API 介绍:
public boolean onJsAlert (WebView view, String url, String message, JsResult result)
Tell the client to display a javascript alert dialog. If the client returns true, WebView will assume that the client will handle the dialog. If the client returns false, it will continue execution.
告知客户端将显示一个alert dialog; 如果方法返回了true, 那么webview就会来自行处理这个dialog; 如果返回了false,则会继续执行下去,webview不进行处理;
在Android中,我们一般重写onJsAlert
方法,会将参数中的message信息用Toast的形式弹出以告知用户,代码如下;
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。
result.confirm();
return true;
或者我们可以自行弹出一个Dialog,覆盖默认的显示界面,代码如下:
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
final AlertDialog.Builder builder = new AlertDialog.Builder(view
.getContext());
builder.setTitle("测试自定义对话框").setMessage(message)
.setPositiveButton("确定", null);
//这里不需要绑定按键事件
//可自行屏蔽keycode按键
builder.setOnKeyListener(new DialogInterface.OnKeyListener()
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event)
Log.e(TAG,"keyCode==" + keyCode + "event=" + event);
return true;
);
//禁止响应按back键的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
result.confirm();//因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。
return true;
3.1.2 自定义onJsConfirm
用法与onJsAlert
基本一样,直接上代码:
@Override
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result)
final AlertDialog.Builder builder = new AlertDialog.Builder(view
.getContext());
builder.setTitle("webview测试confirm对话框")
.setMessage(message)
.setPositiveButton("确定", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
result.confirm();
)
.setNeutralButton("取消", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
result.cancel();
);
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
@Override
public void onCancel(DialogInterface dialog)
result.cancel();
);
//屏蔽keycode的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new DialogInterface.OnKeyListener()
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event)
Log.e(TAG, "keyCode==" + keyCode + "event=" + event);
return true;
);
//禁止响应按back键的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
3.1.3 自定义 onJsPrompt
直接上代码,大致用法一样,只不过个别参数不同:
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result)
final AlertDialog.Builder builder = new AlertDialog.Builder(view
.getContext());
builder.setTitle("webview测试prompt对话框").setMessage(message);
final EditText et = new EditText(view.getContext());
et.setSingleLine();
et.setText(defaultValue);
builder.setView(et);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
result.confirm(et.getText().toString());
).setNeutralButton("取消", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
result.cancel();
);
//屏蔽keycode按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new DialogInterface.OnKeyListener()
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event)
Log.e(TAG, "keyCode==" + keyCode + "event=" + event);
return true;
);
//禁止响应按back键的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
4. 使用websettings让你的webview更加强大
webview获取到websettings之后,可以对当前的webview进行各种设置,如 Js交互开启,缩放,支持插件等等,我们直接以代码为例,代码中对每个功能点都进行了详细说明,请小伙伴参阅;
WebSettings webSettings = webView.getSettings();
//支持获取手势焦点,输入用户名、密码或其他
webView.requestFocusFromTouch();
//支持js交互
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
//设置自适应屏幕,需要与setLoadWithOverviewMode合用
webSettings.setUseWideViewPort(true); //可以将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
//支持缩放,默认为true。是setBuiltInZoomControls的前提。
//若setSupportZoom是false,则该WebView不可缩放,这个不管setBuiltInZoomControls设置什么都不能缩放。
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
//提高渲染的优先级
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局
webSettings.supportMultipleWindows(); //支持多窗口
webSettings.setAllowFileAccess(true); //设置可以访问文件
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
好了,上面就是webview的一些简单用法,后面我们将对webview的缓存机制,前进回退操作,与js互调,避免webview内存泄露等问题进行逐一分析,希望我的文字能在你需要的时候帮到你, 愿大家有美好的一天…..
以上是关于原来你是这样的WebView的主要内容,如果未能解决你的问题,请参考以下文章