1.基本使用
首先要添加网络权限<uses–permission android:name=”android.permission.INTERNET”>
从Android9.0(API 28)开始默认不再支持直接load未加密的url,解决方法是在manifest 中application节点添加android:usesCleartextTraffic=”true“
webView.loadUrl("http://game.163.com")
val webSetting: WebSettings = webView.settings
webSetting.javaScriptEnabled = true
webView.webViewClient = object: WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
url?.let { view?.loadUrl(it) }
return super.shouldOverrideUrlLoading(view, url)
}
}
如果不给webView.webViewClient赋值那么它会在浏览器中打开这个网页,而不是在WebView中打开,如果是加载本地的html文件,需要以file为协议开头:
webView.loadUrl("file:///android_asset/my.html")
注意:加载本地的html时不需要设置WebViewClient
还有几个方法:
webSettings webSetting = mWebView.getSettings();
webSetting.setJavaScriptEnabled(true);//启用js
webSetting.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//优先使用缓存
//自适应屏幕
webSetting.setUseWideViewPort(true);
webSetting.setLoadWithOverviewMode(true);
webSetting.setSupportZoom(true);//支持缩放
webSetting.setBuiltInZoomControls(true);//设置出现缩放工具
webSetting.requestFocusFromTouch();//支持获取手势焦点
val webSettings = mWebView.getSettings()
webSettings.javaScriptEnabled = true
webView.addJavascriptInterface(this, "android")
webView.loadUrl("file:///android_asset/web.html")
fun toastMessage(message: String) {
Toast.makeText(applicationContext, "通过Natvie传递的Toast:$message", Toast.LENGTH_LONG).show()
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<h1>webview示例</h1>
<input type="button" value="js调native" onclick="ok()">
</head>
<body>
<script type="text/javascript">
function ok() {
android.toastMessage("哈哈,i m webview msg");
}
</script>
</body>
</html>
我们可以看到直接用addJavaScriptInterface(this, “android“)把整个类作为对象传给了WebView,这个对象名为“android”。但这样会有很大风险,一般我们不会直接传this,而是传入一个内部类对象,而这个内部类是专门用来和js交互的:
inner class JsBridge {
@JavascriptInterface
fun toastMessage(message: String) {
Toast.makeText(applicationContext, "通过Natvie传递的Toast:$message", Toast.LENGTH_LONG).show()
}
}
注入方法:mWebView.addJavascriptInterface(new JSBridge(), “android“); 为了更好地处理addJavascriptInterface()的安全性问题,在android4.2(17)之后只允许有@JavascriptInterface注解的方法可以和js交互
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<h1 id="h">欢迎光临启舰的blog</h1>
</head>
<body>
<script type="text/javascript">
function sum(i,m) {
document.getElementById("h").innerHTML= (i+m);
}
</script>
</body>
</html>
val webSettings = mWebView.getSettings()
webSettings.javaScriptEnabled = true
webView.loadUrl("file:///android_asset/web.html");
mBtn.setOnClickListener {
webView.loadUrl("javascript:sum(3,8)")
}
如果js的方法有返回值,要在java中搞到这个返回值要怎么做呢?Android4.4之后:
js:
function sum(i, m) {
document.getElementById("h").innerHTML = (i + m);
return i + m;
}
Android:
webView.evaluateJavascript("sum(i, m)", object: ValueCallback<String> {
override fun onReceiveValue(p0: String?) {
Log.i("TAG", "result: $p0")
}
})
4.WebViewClient
这个类提供了一些加载网页时的回调方法:
//在开始加载网页时会回调
public void onPageStarted(WebView view, String url, Bitmap favicon)
//在结束加载网页时会回调
public void onPageFinished(WebView view, String url)
//拦截 url 跳转,在里边添加点击链接跳转或者操作
public boolean shouldOverrideUrlLoading(WebView view, String url)
//加载错误的时候会回调,在其中可做错误处理,比如再请求加载一次,或者提示404的错误页面
public void onReceivedError(WebView view, int errorCode,String description, String failingUrl)
//当接收到https错误时,会回调此函数,在其中可以做错误处理
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error)
//在每一次请求资源时,都会通过这个函数来回调
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
return null;
}
另外通过重写shouldOverrideUrlLoading,可以实现对网页中超链接的拦截
webView.webViewClient = object: WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
url?.let {
if (it.contains("blog.csdn.net")) {
view?.loadUrl("http://www.baidu.com");//在当前webview加载的url中包含“blog.csdn.net”,则将其转换成”www.baidu.com”
} else {
view?.loadUrl(it)
}
return true
}
return false
}
}
而且如果是return true就告诉系统我们已经拦截了URL并进行了处理,不要再去加载默认的URL
所以要想在不满足条件的情况下继续加载原URL就必须手写else代码块重新加载原URL,如果不写
这个else判断,那么当前URL不满足if里面的条件时他也不会去加载原URL,就会产生白屏。所以,一般我们建议使用return false; 这两段代码的效果是一样的:
webView.webViewClient = object: WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
url?.let {
if (it.contains("blog.csdn.net")) {
view?.loadUrl("http://www.baidu.com");//在当前webview加载的url中包含“blog.csdn.net”,则将其转换成”www.baidu.com”
}
return false
}
return false
}
}
5.webView内下载文件监听:DownloadListener
在webview加载的html页面中如果发生下载文件的事件就会触发DownloadListener响应,前提是必须webSettings.javaScriptEnabled置为true,否则点击下载按钮的时候无法触发任何响应:
webView.setDownloadListener { url, userAgent, contentDisposition, mimeType, contentLength ->
Log.i("TAG", "url:$url n" +
"userAgent:$userAgent n" +
"contentDisposition:$contentDisposition n" +
"mimeType:$mimeType n" +
"contentLength:$contentLength")
progressDialog.show()
lifecycleScope.launch {
if (url.endsWith(".apk")) {
val msg = download(url)
Toast.makeText(this@MainActivity, "$msg", Toast.LENGTH_SHORT).show()
// val uri = Uri.parse(url) //或者直接跳系统的下载进程
// val intent = Intent(Intent.ACTION_VIEW, uri)
// startActivity(intent)
}
progressDialog.dismiss()
}
}
private suspend fun download(url: String): String {
return withContext(Dispatchers.IO) {
try {
val httpUrl = URL(url)
val conn = httpUrl.openConnection() as HttpURLConnection
conn.doInput = true
conn.readTimeout = 3000;//设置读取超时的毫秒数
conn.connectTimeout = 3000;//设置连接超时的毫秒数
val connIn = conn.inputStream
val loadFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val apkFile = File(loadFile, "111.apk")
val connOut = FileOutputStream(apkFile)
val b = ByteArray(8 * 1024)
var len = 0
do {
len = connIn.read(b)
if (len != -1) {
connOut.write(b, 0, len)
} else {
break
}
} while (true)
connOut.close()
connIn.close()
"success!"
} catch (e: Exception) {
Log.e("TAG", "$e")
"fail!"
}
}
}
6.返回键
如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件,覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
//改写物理返回键的逻辑
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (webView.canGoBack()) {
webView.goBack() //返回上一页面
return true
} else {
exitProcess(0) //退出程序
}
}
return super.onKeyDown(keyCode, event)
}
val uri = Uri.parse("http://www.example.com")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
原文地址:https://blog.csdn.net/qq_37159335/article/details/125273562
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_48286.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!