现在的APP,大多是NA+H5的,也就是集合了Native APP和Web APP的优点,既保证了用户体验,又使得APP在一定程度上具备动态更新的能力,同时又利于跨平台开发,减少了人力成本。
一、Java调用JavaScript
Java调用JS很简单,
mWebView.loadUrl("javascript:toast()");
让WebView加载本地html,并调用JS中的toast函数,
本地的html如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
function toast() {
alert("xxxx");
}
</script>
</body>
</html>
Java代码如下
public class MyActivity extends Activity {
private WebView mWebView;
private Button mBtn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webview);
mBtn = (Button) findViewById(R.id.btn);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/web.html");
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mWebView.loadUrl("javascript:toast()");
}
});
}
}
二、JavaScript调用Java
需要三步
(1)setJavaScriptEnabled来启用JS
(2)对暴露给JS调用的方法增加@JavascriptInterface注解
(3)在JS中调用Java暴露的方法
以从Java获取WebView加载的html页面内容为例。当WebView把html加载完成后,JS调用Java暴露的方法,把html页面的内容回吐给Java。
代码如下:
public class WebViewTestActivity extends Activity {
private static final String TAG = "WebViewTestActivity";
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_test_layout);
initView();
}
@Override
public void onResume() {
super.onResume();
}
@SuppressLint("SetJavaScriptEnabled")
private void initView() {
webView = (WebView) findViewById(R.id.webView);
//启用支持javascript
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JSBridge(), "android");
// 必须在主线程中
webView.loadUrl("http://hello2mao.github.io/pages/about.html");
webView.setWebViewClient(new WebViewClient() {
// 依然在webview打开新页面
// 拦截 url 跳转,在里边添加点击链接跳转或者操作
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
// 在WebView开始加载网页时调用
@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);
// 通过内部类定义的方法获取html页面加载的内容,这个需要添加在webview加载完成后的回调中
view.loadUrl("javascript:window.android.show(document.body.innerHTML);");
}
});
}
public class JSBridge {
@JavascriptInterface
public void show(String data) {
// 这里的data就webview加载的内容,即使页面跳转页都可以获取到,这样就可以做自己的处理了
Log.d("LOG_TAG", data);
saveFile("<html>" + data + "</html>");
}
}
private static void saveFile(String str) {
String filePath = null;
boolean hasSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if (hasSDCard) { // SD卡根目录的hello.text
filePath = Environment.getExternalStorageDirectory().toString() + File.separator + "hello.txt";
} else // 系统下载缓存根目录的hello.text
filePath = Environment.getDownloadCacheDirectory().toString() + File.separator + "hello.txt";
try {
File file = new File(filePath);
if (!file.exists()) {
File dir = new File(file.getParent());
dir.mkdirs();
file.createNewFile();
}
FileOutputStream outStream = new FileOutputStream(file);
outStream.write(str.getBytes());
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}