在项目开发中遇到了Js调取不到android端的问题,查看了挺多博文,并没有叙述到我遇见的问题类型!
当然我遇到的问题可以说是疏忽而至,但哪一个错误不是无心过失?
故根据网上目前可查信息总结了交互中遇到的一些问题,有的是当前很多博文已有的,有的是我自己遇到的~
在开始错误总结之前,可以通过我写的另外一篇博文学习俩端交互,看看你的交互方式是否与我相同~
错误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>;
}