Android进阶之路 - Andorid与JS交互可能出错的原因

在项目开发中遇到了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>;
}

猜你喜欢

转载自blog.csdn.net/qq_20451879/article/details/80484853