有时候,我们需要在应用内集成显示网页,然而加载和显示网页的任务通常都是浏览器的任务,针对这个需求Android提供了WebView控件,借助它可以在应用内展示引入的网页并与之交互。
WebView的基本用法
1. 添加网络访问权限,设置WebView控件
<uses-permission android:name="android.permission.INTERNET"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.MainActivity">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2. 加载显示的Url
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private String url = "https://www.baidu.com";
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
loadWeb();
}
private void loadWeb() {
//允许网页加载JavaScript脚本
mWebView.getSettings().setJavaScriptEnabled(true);
//当网页跳转时,仍旧在本页面内
mWebView.setWebViewClient(new WebViewClient());
mWebView.loadUrl(url);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//响应Back键,回退网页时仍在本页面
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
private void initView() {
mWebView = findViewById(R.id.web_view);
}
}
补充,打开不同存储区域的Html
1.打开assets
mWebView.loadUrl("file:///android_asset/index.html");
2.SD卡中的Html
mWebView.loadUrl(“content://com.android.htmlfileprovider/sdcard/index.html”);
3.服务端指定Url的Html。
mWebView.loadUrl(“http://www.baidu.com”);
WebView提供的API
1.WebViewClient
用来监控webview网页的加载状态
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view,
WebResourceRequest request) {
//发生重定向,自己处理
return true;
}
@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 void onReceivedError(WebView view, WebResourceRequest request,
WebResourceError error) {
//页面出现错误回调
super.onReceivedError(view, request, error);
}
});
2.WebChromeClient
处理网页内容与Js交互
mWebView.setWebChromeClient(new WebChromeClient(){
@Override
public boolean onJsAlert(WebView view, String url,
String message, JsResult result) {
//接收Alert
Toast.makeText(mContext,message,Toast.LENGTH_SHORT).show();
result.confirm();
return true;
}
@Override
public boolean onJsPrompt(WebView view, String url,
String message, String defaultValue,
JsPromptResult result) {
result.confirm("Pay Success");
return true;
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
//接收网页图标
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
//接收网页标题
}
});
3.WebSettings
设置webview的各种详细参数
WebSettings settings = mWebView.getSettings();
设置网页文字大小
settings.setDefaultFontSize(30);
允许网页加载JavaScript脚本
settings.setJavaScriptEnabled(true);
settings.setAppCacheEnabled(true);
settings.setBuiltInZoomControls(true);
WebView与H5交互
Android与Html的交互,实际就是Android原生API与Js的交互。
分两种情况
原生调用Js
Js调用原生
1. 准备assets下的目录
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>演示网站</title>
<script type="text/javascript">
<!--Js调用原生-->
function getAndroidMethod(){
androidApp.androidMethod();
}
<!--原生调用Js-->
function showName(name){
document.getElementById("userName").value = name;
}
</script>
</head>
<body>
<input type="text" id="userName" placeholder="显示Android原生发送过来的数据">
<br/>
<button onclick="getAndroidMethod()">调用Android原生的方法</button>
</body>
</html>
2. 设置Android界面
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.activity.MainActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/btn_get_user_name"
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="Get UserName"
android:textAllCaps="false" />
</LinearLayout>
3. 定义相互通信
public class MainActivity extends AppCompatActivity {
private WebView mWebView;
private Context mContext;
private Button mBtnGetUserName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
initView();
loadWeb();
}
private void loadWeb() {
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/index.html");
mWebView.setWebViewClient(new WebViewClient());
final WebAppInterface webAppInterface = new WebAppInterface();
//相互通信的方法,和Js调用原生时需要的接口
mWebView.addJavascriptInterface(webAppInterface, "androidApp");
mBtnGetUserName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
webAppInterface.showName("原生调用Js传递数据");
}
});
}
//最好定义个接口,再准备实现类,这里为了演示方便就不写了
class WebAppInterface {
//Js通过定义的原生接口调用此方法
//一定加注解否则可能会报错
@JavascriptInterface
public void androidMethod() {
Toast.makeText(mContext, "Android原生方法", Toast.LENGTH_SHORT).show();
}
public void showName(String name) {
//原生调用Js
mWebView.loadUrl("javascript:showName('" + name + "')");
}
}
private void initView() {
mWebView = findViewById(R.id.webView);
mBtnGetUserName = findViewById(R.id.btn_get_user_name);
}
}