WebView
预备知识
新建asserts文件:
assets目录下主要存放四种文件:文本文件、图像文件、网页文件(包括html中引用的js/ccs/jpg等资源)、音频视频文件
加载网页
- 加载URL(网络或者本地asserts文件夹下的html文件)
- 加载html代码
- Native和JavaScript相互调用(JS和WebView混合调用)
加载网络URL
- webview.loadUrl(“http://m.tiantiantech.cn”) ;
加载asserts下的html文件
- webview.loadUrl(“file:///android_asset/test.html”); // 没有s和r,就asset
加载html代码
- webview.loadData();
- webview.loadDataWithBaseURL();
按下返回键,默认是退出Activity,如果是希望WebView内页面后退
重写onKeyDown方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()){
webview.goBack();
return true; // true表示处理完该事件 , false表示该事件可以传递下去
}
return super.onKeyDown(keyCode, event);
}
webview其他方法:
webview.canGoBack()
webview.goBack()
webview.canGoForward()
webview.goForward()
webview.canGoBackOrForward(int steps)
webview.goBackOrForward(int steps)
添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
具体代码(加载百度):
public class WebViewBaidu extends AppCompatActivity {
WebView mWvMain;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view_baidu);
mWvMain = findViewById(R.id.web_view_baidu);
mWvMain.getSettings().setJavaScriptEnabled(true);
mWvMain.setWebViewClient(new MyWebViewClient());
mWvMain.setWebChromeClient(new MyWebChromeClient());
mWvMain.loadUrl("https://m.baidu.com"); // mobile移动端地址
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if((keyCode == KeyEvent.KEYCODE_BACK) && mWvMain.canGoBack()){
mWvMain.goBack();;
return true;
}else {//如果WebView不能回退
//提示应用是否退出程序
new AlertDialog.Builder(WebViewBaidu.this).setTitle("提示")
.setMessage("确定退出浏览器吗?").setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
WebViewBaidu.this.finish();//退出程序
}
}).setNegativeButton("取消", null).show();
return super.onKeyDown(keyCode, event);
}
return super.onKeyDown(keyCode, event);
}
class MyWebChromeClient extends 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);
setTitle(title); // 修改网页标题
}
}
class MyWebViewClient extends WebViewClient {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.d("WebView","onPageStarted...");
// mWvMain.loadUrl("javascript:alert('loading')"); // 用js弹出对话框
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d("WebView","onPageFinished");
// mWvMain.loadUrl("javascript:alert('loaded')"); // 用js弹出对话框
}
}
}
WebViewClient与WebChromeClient的区别
在WebView的设计中,不是什么事都要WebView类干的,有些杂事是分给其他人的,这样WebView专心干好自己的解析、渲染工作就行了。WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括:
onLoadResource |
---|
onPageStart |
onPageFinish |
onReceiveError |
onReceivedHttpAuthRequest |
WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如
onCloseWindow(关闭WebView) |
---|
onCreateWindow() |
onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出) |
onJsPrompt |
onJsConfirm |
onProgressChanged |
onReceivedIcon |
onReceivedTitle |
解析并执行JS操作的方法:
// mWvMain.evaluateJavascript(“ ”,null);
// mWvMain.loadUrl("");
常出现的问题
1.Android WebView 加载失败(net::ERR_CLEARTEXT_NOT_PERMITTED)
解锁正确姿势:
首先保证App申明了网络权限
<uses-permission android:name="android.permission.INTERNET" />
然后在manifest 中application节点添加
android:usesCleartextTraffic="true"
2.net:err_unknown_url_scheme
R文件
当 Android 应用程序被编译,会自动生成一个 R 类,其中包含了所有 res/ 目录下资源(res资源:如layout、string、drawable等)。
如何使用R文件
1、 在java文件中使用R文件
1)使用res资源下: R.子类.资源名(资源标识符) R.type.name
//字符
R.string.name1
R.string.name2
//图片
R.drawable.icon1
R.drawable.icon2
//布局
R.layout.first_layout
R.layout.second_layout
//....
2)使用android自带的资源下,android.R.type.name
只需要再前面加上android. 以申明来自Android系统
2、在XML中使用R文件
1)在res资源下,@[package:]type/name(使用我们自己包下的资源可以省略 package)
@drawable/icon
/*
其中@代表R.java类
drawable代表的是R.java中的静态内部类drawable
icon代表静态内部类drawable中的静态属性icon
而该属性可以指向 res 目录下的“drawable-*dpi”中的 icon.png 图标
*/
2)在android内置资源下,则要添上包名“android:”
android:textColor=”@android:color/red”
最后说明一下“@+id/string_name”表达式
顺便说一下,在布局文件当中我们需要为一些组件添加 Id 属性作为标示,可以使
用如下的表达式“@+id/string_name”
其中“+”表示在 R.java 的名为 id 的内部类中添加一条记录。如”@+id/button”的含义是在 R.java 文件中的 id 这个静态内部类添加一条常量名为 button,该常量就是该资源的标识符。如果 id 这个静态内部类不存在,则会先生成它。
通过该方式生成的资源标识符,仍然可以以“@id/string_name”的方式引用。
参考博客:
https://blog.youkuaiyun.com/u012810020/article/details/51820240
https://blog.youkuaiyun.com/u012810020/article/details/51820240