在平常的开发中我们一般都会使用到混合开发,比如H5+原生,如果你的app使用到H5开发,那么webview使用是不可或缺的。所以掌握WebView的知识是多么重要。 本文要带你溜WebView,让你掌握WebView的基本开发,包括与javaSript的交互。 先看下效果图
这里首先点击“hello world” 然后javaSript弹出一个alert弹框,接着JavaScript调用java的clickText函数,通过回调,弹出一个toast提示。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
tools:context="lwj.com.webview.WebViewActivity">
<WebView
android:id="@+id/id_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
布局就一个webview显示网页
public class WebViewActivity extends AppCompatActivity {
private static final String TAG = "WebViewActivity";
private WebView webView;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
webView = (WebView) this.findViewById(R.id.id_webview);
WebSettings webSetting = webView.getSettings();
webSetting.setDefaultTextEncodingName("utf-8");
webSetting.setJavaScriptEnabled(true);//支持js
webSetting.setUseWideViewPort(false);//设置此属性,可任意缩放比例
webSetting.setTextZoom(100);//设置字体,相对于正常字体的百分比
webSetting.setLoadWithOverviewMode(true);
webSetting.setDomStorageEnabled(true);// 开启DOM storage
webView.setWebChromeClient(webChromeClient);
webView.setWebViewClient(webViewClient);
String s1 = getHtmlStr("hello world");
webView.loadData(s1, "text/html", "utf-8");
//与js交互
JsToAndroidInterface jsToAndroid = new JsToAndroidInterface();
jsToAndroid.setOnClickListener(new JsToAndroidInterface.OnTextClickListener() {
@Override
public void onTextClick(final String str) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(WebViewActivity.this,str,Toast.LENGTH_SHORT).show();
}
});
}
});
webView.addJavascriptInterface(jsToAndroid, JsToAndroidInterface.INTERFACE_NAME);
}
/**
* html数据
* @param str
* @return
*/
public static String getHtmlStr(String str) {
StringBuilder builder = null;
try {
builder = new StringBuilder();
builder.append("<html><head>");
builder.append(" <script language=\"javascript\">function s(){\n" +
"alert(\""+str+"!\");\n" +
"window.clickOnAndroid.clickText(\""+str+"\");\n" +
"}</script>");
builder.append("</head><body><div class=\"container\"><div class=\"content\">");
builder.append("<a href=\"javascript:void(0);\" onclick=\"s()\">").append(str).append("</a>");
builder.append("</div></div></body></html>");
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
/**
* 处理各种通知
* 请求事件相关
*/
private WebViewClient webViewClient = new WebViewClient() {
/**
* 开始加载页面回调
* @param view
* @param url
* @param favicon
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.i(TAG, "onPageStarted");
super.onPageStarted(view, url, favicon);
}
/**
* 拦截url跳转
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//当前的webview跳转
webView.loadUrl(url);
return true;
}
/**
* 在每一次请求资源时回调
* @param view
* @param request
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.i(TAG, "shouldOverrideUrlLoading");
return super.shouldOverrideUrlLoading(view, request);
}
/**
* 加载完成回调
* @param view
* @param url
*/
@Override
public void onPageFinished(WebView view, String url) {
Log.i(TAG, "onPageFinished");
super.onPageFinished(view, url);
}
/**
* 加载错误回调
* 在这做错误处理
* @param view
* @param request
* @param error
*/
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
Log.i(TAG, "onReceivedError");
super.onReceivedError(view, request, error);
}
/**
* https错误回调
* 可做错误处理
* @param view
* @param request
* @param errorResponse
*/
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
Log.i(TAG, "onReceivedHttpError");
super.onReceivedHttpError(view, request, errorResponse);
}
/**
* 加载页面资源回调
* @param view
* @param url
*/
@Override
public void onLoadResource(WebView view, String url) {
Log.i(TAG, "onLoadResource");
super.onLoadResource(view, url);
}
};
/**
* 处理浏览器相关的事件
* 如处理JavaScript的对话框
* 图标、title、加载进度
*/
private WebChromeClient webChromeClient = new WebChromeClient() {
/**
* javasript 的alert弹框调用
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
Log.i(TAG, "onJsAlert");
AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
dlg.setTitle("提示");
dlg.setMessage(message);
dlg.setButton(AlertDialog.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
result.confirm();
}
});
dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
result.cancel();
}
});
dlg.show();
return true;
}
/**
* js的Confirm弹框
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
dlg.setTitle("提示");
dlg.setMessage(message);
dlg.setButton(AlertDialog.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
result.confirm();
}
});
dlg.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
result.cancel();
}
});
dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
result.cancel();
}
});
dlg.show();
return true;
}
/**
* 处理js prompt弹框
* @param view
* @param url
* @param message
* @param defaultValue
* @param result
* @return
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
Log.i(TAG, "onJsPrompt");
return super.onJsPrompt(view, url, message, defaultValue, result);
}
/**
* 加载网页进度条
* @param view
* @param newProgress
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
Log.i(TAG, "onProgressChanged" + newProgress);
super.onProgressChanged(view, newProgress);
}
/**
* 网页的title
* @param view
* @param title
*/
@Override
public void onReceivedTitle(WebView view, String title) {
Log.i(TAG, "onReceivedTitle" + title);
super.onReceivedTitle(view, title);
}
};
/**
* 实现在历史页面中 Back
* 要在当前 Activity
* 中处理并消费掉该 Back事件:
*/
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
这里首先通过WebSettings设置webview支持的类型,包括与JavaScript交互的设置,然后加载html数据,并且设置与JavaScript交互的对象(JsToAndroidInterface),还有关于WebViewClient和WebChromeClient介绍,里面方法的作用与处理,具体的可以看注释,最后对webView.goBack()的处理.
public class JsToAndroidInterface {
public static final String INTERFACE_NAME = "clickOnAndroid";
private OnTextClickListener mClickListener;
/**
* 供js调用函数
* @param str
*/
@JavascriptInterface
public void clickText(final String str)
{
if(mClickListener != null)
{
mClickListener.onTextClick(str);
}
}
/**
* 回调接口
*/
public interface OnTextClickListener
{
void onTextClick(String str);
}
/**
* 设置回调
* @param listener
*/
public void setOnClickListener(OnTextClickListener listener)
{
mClickListener = listener;
}
}
这是与JavaScript交互的对象,JavaScript调用clickText,通过回调给用户调用. 看了本文,应该都了解webview的常用知识了吧.