在项目开发中我遇到了一些俩端交互的问题!
之后查看了挺多博文,但是并没有讲述到我遇见的问题类型!!
当然我遇到的问题可以说是疏忽而至,但哪一个错误不是无心过失?
故最后在结合自身所遇问题与网上可查问题总结了此篇博文,一点一滴、一分一秒进步吧~
我那些关于WebView的回忆 ~ 包含入门使用、优化加载样式、监听加载状态、各场景后退键处理、俩端交互流程、header、user-agent传值、交互常见问题、较全API整合
业务实战
在开始错误总结之前,可以通过我写的另外一篇博文学习俩端交互,看看你的交互方式是否与我相同~
错误1:未允许Js交互
正确方式
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
错误2:执行交互的类内方法,未声明 @JavascriptInterface 注解
正确方式
class ActivityData {
@JavascriptInterface
void onBackHome() {
startActivity(ActivityDetailActivity.this, MainActivity.class);
}
}
错误3:未绑定一个java对象到webview
正确方式
//参数1,2都是可变的,参数1对应的是我们用户交互的实体类,参数2对应的是我们提供给前端调用的类名
mWebView.addJavascriptInterface(new LoginData(this), "LoginData");
错误4:如上述设置都已拥有,Js调用仍失败,报找不到该方法 - 未声明权限 !
错误方式:Android与JS用于交互的方法未声明权限!!!
//webView设置处,设置允许js交互,同时定义类名
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new ActivityData(), "goBack");
//特别注意点: 这里是我用于交互的class
class ActivityData {
@JavascriptInterface
void onBackHome() {
startActivity(ActivityDetailActivity.this, MainActivity.class);
}
@JavascriptInterface
void share() {
shareData();
}
}
正确方式:该类需声明权限,而不要因为偷懒就少写了 public !!!
//webView设置处,设置允许js交互,同时定义类名
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new ActivityData(), "goBack");
//特别注意点:权限声明!
public class ActivityData {
@JavascriptInterface
public void onBackHome() {
startActivity(ActivityDetailActivity.this, MainActivity.class);
}
@JavascriptInterface
public void share() {
shareData();
}
}
错误5:如上述设置都已拥有,Js调用仍失败,报找不到该方法 - 查看是否被混淆!
build.app
buildTypes {
release {
//混淆配置
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
图如下:
如已进行混淆,则我们进行反混淆配置,正确方式:
-
防止被混淆的配置区间
-
- 通用配置
#保留annotation, 例如 @JavascriptInterface 等 annotation
-keepattributes *Annotation*
#保留跟 javascript相关的属性
-keepattributes JavascriptInterface
#保留JavascriptInterface中的方法
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
#这个根据自己的project来设置,这个类用来与js交互,所以这个类中的 字段 ,方法, 等尽量保持
#com.packgename.custom.WVJBWebViewClient此处换为自己对应的包名类名!
-keepclassmembers public class com.packgename.custom.WVJBWebViewClient{
<fields>;
<methods>;
public *;
private *;
}
配置通用规则之后,如JS调用还出现问题的话,通过log 日志,以及mapping文件的查看,找出问题原因,如果是因为内部类被混淆(包含类中字段)的话,需要再添加以下代码:
#注意:其中的com.packgename.custom.WVJBWebViewClient$WVJBMessage需要替换为自己的包名,外部类名与内部类名!
#这个类 必须保留,这个类在WVJBWebViewClient中传递数据,如果被混淆 会导致一些callback无法调用
-keep class com.packgename.custom.WVJBWebViewClient$WVJBMessage
#类中成员的变量名也不能混淆,这些变量名被作为json中的字段,不能改变。
-keepclassmembers class com.packgename.custom.WVJBWebViewClient$WVJBMessage{
<fields>;
}
错误6:webview无法重定向
WebSettings setting = mWebView.getSettings();
//开启DOM storage API功能
setting.setDomStorageEnabled(true);
错误7:android与H5交互调用js方法无效问题
随机一眼,看到有这样的问题,故此记录一下 ;正常情况一般常规使用方式都是可用的~~~
借鉴自 android与H5交互调用js方法无效问题
无效代码
mWebView.loadUrl("javascript:do()");
修改后代码
mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:callIng()");
}
});