1.初始化
1.布局中添加webview控件
2.让webview支持js
webView.getSettings().setJavaScriptEnabled(true);
3.加载网页
webView.loadUrl(url);
4.让webview加载网页
id_webview.setWebChromeClient(new WebChromeClient());
2.原生调用JS方法
1.原生调用js不带返回值的方法
js带参数的方法 不带返回值
function nativeCallToJS(param) {
alert(param);
}
//原生调用js 不带返回值
public void nativeCallToJS1(){
js方法带参数的 参数为字符串需要加单引号 javascript:方法名 (参数名)
id_webview.loadUrl("javascript:nativeCallToJS("+"'hello xiaocheng'"+")");
}
2.原生调用js带返回值的方法
js带返回值方法
function returnResult(){
return 1 + 2;
}
//原生调用js 获取返回值 returnResult: js定义的方法 ()不能少
public void nativeCallToJS2(){
id_webview.evaluateJavascript("returnResult()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Toast.makeText(MainActivity.this,"我是调用js返回的数据:"+value,Toast.LENGTH_LONG).show();
}
});
}
3.JS调用原生方法
@JavascriptInterface注解表面这个方法是给js调用的
1. 通过addJavascriptInterface将MainActiviy所对应的对象mainActivity注入到WebView中了。
2. 查看js调用原生是否在主线程 因为原生只能在主线程更新ui
原生方法
@JavascriptInterface
public void jsCallNativeLookThread(String msg){
Log.e("js调用原生方法是不是在主线程",Thread.currentThread().getName().equals("main")+"");
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
id_webview.post(new Runnable() {
@Override
public void run() {
id_webview.loadUrl("javascript:nativeCallToJS("+"'你好啊,小成哥!'"+")");
}
});
}
js中调用的方法 mainActivity必须与上面绑定的对象一样
function jsCallNativeLookThread(param) {
window.mainActivity.jsCallNativeLookThread(param);
}
3. js调用原生获取原生返回值
原生方法
@JavascriptInterface
public int jsCallNativeGetResult(int num, int num1) {
return num + num1;
}
js调用 把计算的结果显示出来
function jsCallNativeGetResult(num1,num2) {
document.getElementById("font").innerText = "调用原生计算的结果:"+
window.mainActivity.jsCallNativeGetResult(num1,num2);
}
4. js调用原生原生跳页传值
原生方法
@JavascriptInterface
public void jsCallNativeToActivity(String msg){
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("msg",msg);
startActivity(intent);
}
js调用
function jsCallNativeToActivity(param){
window.mainActivity.jsCallNativeToActivity(param);
}
5. js调用原生保存网络图片到sd卡
原生方法 Android6.0以上需要动态权限处理 同时需要在清单文件中添加sd卡读写权限和网络权限
private String imagUrl;
//Js调用原生方法保持图片到sd卡
@JavascriptInterface
public void jsCallNativeSaveImg(String imgUrl){
this.imagUrl = imgUrl;
boolean checkResult = PermissionsCheckUtils.checkPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE);
if(!checkResult){
Log.e("saveImgToSdcard","权限未通过");
requestPermissions(this,STORAGECODE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE);
}else {
saveImage(imgUrl);
}
}
//安卓6.0以上需要动态获取权限
private void requestPermissions(Activity activity, int requestCode,String... permissions){
ActivityCompat.requestPermissions(activity,permissions,requestCode);
}
//权限处理请求返回值
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//判断请求码,确定当前申请的权限
if (requestCode == STORAGECODE) {
//判断权限是否申请通过
if (grantResults.length == 2 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//授权成功
saveImage(imagUrl);
} else {
//授权失败
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
//保存图片方法
private void saveImage(String imgUrl) {
Log.e("saveImg","图片地址:"+imgUrl);
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL(imgUrl);
if(url != null){
is = url.openStream();
}
if(is != null){
Bitmap bitmap = BitmapFactory.decodeStream(is);
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
&& !Environment.isExternalStorageRemovable()){
File targetFile = new File(Environment.getExternalStorageDirectory(),"testImgs");
if(!targetFile.exists()){
targetFile.mkdir();
}
File file = new File(targetFile.getAbsolutePath(), UUID.randomUUID().toString()+".jpg");
fos = new FileOutputStream(file);
//80代表压缩率为20%
bitmap.compress(Bitmap.CompressFormat.JPEG,80,fos);
fos.flush();
fos.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
js调用原生方法保存图片
function jsCallNativeSaveImg() {
var imgUrl = "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3668554427,3084213941&fm=200&gp=0.jpg";
window.mainActivity.jsCallNativeSaveImg(imgUrl);
}
6. html页面中点击事件处理
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Main</title>
<link rel="stylesheet" href="./main.css" type="text/css" />
<script src="./main.js"></script>
</head>
<body>
<div class="layout">
<h3 id="font" style="padding-top:10px">zlc</h3>
<button class="button" onclick="jsCallNativeLookThread('测试线程 ')">js调用Native查看线程</button>
<br/>
<button class="button" onclick="jsCallNativeGetResult(518,2)">js调用Native获取返回值</button>
<br/>
<button class="button" onclick="jsCallNativeToActivity('100')">js调用Native跳页传值</button>
<br/>
<button class="button" onclick="jsCallNativeSaveImg()">js调用native保存图片</button>
</div>
</body>
</html>
4.总结
其实android原生与js互调比想象中简单
5.下载地址