介绍
如果我们需要在应用程序中展示一些页面,只需要简单的使用一下WebView控件就可以了。
WebView展示百度页面
效果图
1.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/wv_baidu"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
2.MainActivity
public class MainActivity extends AppCompatActivity {
private WebView wv_baidu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv_baidu = findViewById(R.id.wv_baidu);
//让WebView支持JavaScript脚本
wv_baidu.getSettings().setJavaScriptEnabled(true);
//传入网址
wv_baidu.loadUrl("http://www.baidu.com");
}
@Override
protected void onDestroy() {
wv_baidu.destroy();
wv_baidu=null;
super.onDestroy();
}
}
3.清单文件添加权限
<uses-permission android:name="android.permission.INTERNET"/>
这时候打开程序就有效果了~
更多设置
设置之前先介绍两个类
WebViewClient
- 主要帮助WebView处理各种通知、请求事件的,有以下常用方法
- onPageFinished 页面请求完成
- onPageStarted 页面开始加载
- shouldOverrideUrlLoading 拦截url
- onReceivedError 访问错误时回调,例如访问网页时报错404,在这个方法回调的时候可以加载错误页面
WebChromeClient
- 主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等,有以下常用方法
- onJsAlert webview不支持js的alert弹窗,需要自己监听然后通过dialog弹窗
- onReceivedTitle 获取网页标题
- onReceivedIcon 获取网页icon
- onProgressChanged 加载进度回调
1.创建WebViewClient实例
private WebViewClient webViewClient = new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
//页面开始加载
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
//页面加载完成
super.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//处理其他情况,比如国内不能访问google,拦截该url
return super.shouldOverrideUrlLoading(view, request);
}
};
2.创建WebChromeClient实例
private WebChromeClient webChromeClient =new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
//加载进度回调
super.onProgressChanged(view, newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
//获取网页标题
super.onReceivedTitle(view, title);
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//因为WebView不支持alert弹窗,在这个方法中用AlertDialog去弹窗
return super.onJsAlert(view, url, message, result);
}
};
3.设置WebViewClient和WebChromeClient
wv_baidu.setWebViewClient(webViewClient);
wv_baidu.setWebChromeClient(webChromeClient);
JS交互
这里通过 WebView的addJavascriptInterface()
进行 对象映射
1.创建myjs.html放在src/main/assets
下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Carson</title>
<script>
function callAndroid(){
// 由于对象映射,所以调用test对象等于调用Android映射的对象
test.hello("js调用了android中的hello方法");
}
</script>
</head>
<body>
<button type="button" id="button1" onclick="callAndroid()">点击调用安卓代码</button>
</body>
</html>
2.创建AndroidtoJs类(我这里是写的内部类,没有新建.java文件),在里面写JS所需要调用的方法
public class AndroidtoJs {
// 定义JS需要调用的方法
// 被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void hello(String msg) {
Toast.makeText(MainActivity.this, "JS调用了Android的hello方法", Toast.LENGTH_SHORT).show();
}
}
3.设置一下
//可以与JS进行交互
wv_baidu.getSettings().setJavaScriptEnabled(true);
// 通过addJavascriptInterface()将Java对象test映射到JS对象
wv_baidu.addJavascriptInterface(new AndroidtoJs(),"test");
//设置一下路径,标准格式如下
wv_baidu.loadUrl("file:///android_asset/myjs.html");
效果
坑
1.WebView内存泄漏
- 当你要用webview的时候,记得最好另外单独开一个进程去使用,并且当这个进程结束时,手动调用
System.exit(0)
。使用此方法,所有因为webview引发的资源无法释放等问题都可以解决
2.getSettings().setBuiltInZoomControls(true) 引发的crush
- 这个方法调用以后 如果你触摸屏幕 弹出那个提示框还没消失的时候 你如果activity结束了 就会报错了。3.0以上 4.4以下很多手机会出现这种情况所以为了规避他,我们通常是在activity的
onDestroy
方法里手动的将webiew设置成setVisibility(View.GONE)
3.onPageFinished 函数到底有用没有?
- 这个函数并没有什么卵用,有的时候是提前结束,有的时候就迟迟无法结束,你信这个函数 还不如信上帝,甚至于
onProgressChanged
这个函数都比onPageFinished
要准一些,更加靠谱的方法是使用onprogresschange
方法代替该方法的功能,当newProgress
为100的时候,即是页面加载完成
4.后台无法释放js 导致耗电
- 如果webview加载的html里 有一些js 一直在执行比如动画之类的东西,如果此刻webview 挂在了后台这些资源是不会被释放 用户也无法感知。。。导致一直占有cpu 耗电特别快,所以大家记住了,如果遇到这种情况 请在
onStop
和onResume
里分别把setJavaScriptEnabled()
;给设置成false和true。 - webview加载网页的时候,会自动创建线程,如果如果使用不当,这些线程会永远在后台运行,导致你的应用耗电量居高不下,这个问题的解决方式是在activity的
onDetory
方法中销毁webview
5.前端最好不要使用了ES6语法
6.webview动态添加到其他布局的时候,在activity销毁的生命周期时,需要主动调用webview.removeallviews
和webview的ondestory
方法释放内存,否则会导致内存泄漏
7.webview硬件加速导致渲染问题,比如加载的时候会有闪屏现象,解决方式就是暂时关闭硬件加速
8.webview导致内存溢出的原因,主要是因为内部类持有外部类的引用导致外部类无法释放的问题
9.关于webview.onPause()
- 通知内核尝试停止所有处理,如动画和地理位置,但是不能停止Js,如果想全局停止Js,可以调用
pauseTimers()
全局停止Js,调用onResume()
恢复。
完结~
https://blog.csdn.net/lowprofile_coding/article/details/77928614
https://blog.csdn.net/carson_ho/article/details/64904691/.
https://www.cnblogs.com/punkisnotdead/p/5062631.html
https://blog.csdn.net/yt522401813/article/details/73397823