这篇文章主要讲解android 中h5与webview交互相关的内容。
首先设置webview与js交互,这里我们需要用到WebSettings这个类:
WebSettings webSettings= binding.myWeb.getSettings();
//设置与js交互
webSettings.setJavaScriptEnabled(true);
//设置可以打开弹框,适用于window.open
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
这里在项目本地放置了html文件,路径main/assets :
My_Hello
接着,我们加载本地的html文件:
具体的方法是file://android_asset/+xxx.html;
webview.loadUrl("file:///android_asset/Test1.html");
至于调用callJS则需要用到webview的post方法:
myWeb.post(new Runnable() {
@Override
public void run() {
myWeb.loadUrl("javascript:callJS()");
}
});
最后我们设置webviewChromClient,重写onJsAlert方法,来响应alert弹框。
class MyWebChromeClent extends WebChromeClient{
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
builder.setMessage(message);
builder.setPositiveButton("confirm", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
return true;
}
}
evaluateJavascript方法是android 4.4以后的新方法;
public void MyEvaluateJavascript(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
binding.myWeb.evaluateJavascript("callJS2()", new ValueCallback() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onReceiveValue(String value) {
Toast.makeText(getApplicationContext(), value, Toast.LENGTH_LONG).show();
}
});
}
}
两个参数,第一个指定js方法,第二个回调js方法的返回值。
我们直接在loadurl后调用下该方法,并把返回值打印下:
。。。返回值为null,什么情况。
这里需要我们注意,如果直接调用这个方法需要保证执行时间在onPageFinished之后,否则onReceiveValue中返回值一直是null。
所以,将调用方法放入onPageFinished
class MyWebViewClient extends WebViewClient{
@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);
MyEvaluateJavascript();
}
}
由于loadurl每次调用都会刷新页面,所以我们在使用的时候结合两种方法一起使用,即19以下用loadUrl,以上使用evaluateJavascript();
android 中内置的addJavascriptInterface进行对象映射,参数两个:
1:object 2:interfaceName
首先定义object,如下:
class MyJavascriptInterface extends Object{
@JavascriptInterface
public String getToken(){
return "这里用户登录token";
}
@JavascriptInterface
public void showToast(String x){
Toast.makeText(MainActivity.this,x,Toast.LENGTH_SHORT).show();
}
}
使用注解JavascriptInterface定义方法;
接着定义在html中调用:
My_Hello
注意:html中的方法需要使用window.来开始,Native就是我们在JavascriptInterface定义的name。
shouldOverrideUrlLoading方法中我们可以进行url拦截,一般处理重定向问题也是在该方法中实现。
另外api21后参数为url的方法已经过时,新增的WebResourceRequest参数:
@Override
@SuppressWarnings("deprecation") // for invoking the old shouldOverrideUrlLoading.
@RequiresApi(21)
public boolean shouldOverrideUrlLoading(@NonNull WebView view,
@NonNull WebResourceRequest request) {
if (Build.VERSION.SDK_INT < 21) return false;
return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
这里不再赘述addJavascriptInterface这中方法的实现,而是通过activity的隐式启动。
首先需要在manifest中定义activity的属性:
html文件中使用如下:
new Activity
使用scheme和host,另外参数拼接。
接着由于是url需要我们在本地处理,所以需要重写shouldOverrideUrlLoading:
class MyWebViewClient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try {
if (url.contains("webtest:")){
Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}catch (Exception e){
}
return super.shouldOverrideUrlLoading(view, url);
}
}
最后是对应的activity中接收参数信息。
Intent intent = getIntent();
String action = intent.getAction();
if (Intent.ACTION_VIEW.equals(action)) {
Uri uri = intent.getData();
String data = uri.toString();
binding.tvParam.setText(data);
}