美文网首页
Android Studio是如何实现AddJavascript

Android Studio是如何实现AddJavascript

作者: sunger | 来源:发表于2017-04-19 10:29 被阅读238次
    效果图

    源码是AddJavascriptInterfaceDetector.java

    接下来我们来看看是如何实现的

    Detector.JavaPsiScanner

    • 用于实现java源码检测的接口
    • 取代了之前的Detector.JavaScanner
       private static final String WEB_VIEW = "android.webkit.WebView";
        private static final String ADD_JAVASCRIPT_INTERFACE = "addJavascriptInterface";
    
        // ---- Implements JavaScanner ----
    
        @Nullable
        @Override
        public List<String> getApplicableMethodNames() {
            return Collections.singletonList(ADD_JAVASCRIPT_INTERFACE);
        }
    
        @Override
        public void visitMethod(@NonNull JavaContext context, @Nullable JavaElementVisitor visitor,
                @NonNull PsiMethodCallExpression node, @NonNull PsiMethod method) {
            // Ignore the issue if we never build for any API less than 17.
            if (context.getMainProject().getMinSdk() >= 17) {
                return;
            }
    
            JavaEvaluator evaluator = context.getEvaluator();
            if (!evaluator.methodMatches(method, WEB_VIEW, true, TYPE_OBJECT, TYPE_STRING)) {
                return;
            }
    
            String message = "`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: " +
                    "JavaScript can use reflection to manipulate application";
            context.report(ISSUE, node, context.getNameLocation(node), message);
        }
    

    核心代码

    • getApplicableMethodNames()

    这个方法用来返回你感兴趣的那些方法调用列表,所以这里设置
    的是字符addJavascriptInterface,此方法配合以下方法使用

    • visitMethod(@NonNull JavaContext context, @Nullable JavaElementVisitor visitor, @NonNull PsiMethodCallExpression node, @NonNull PsiMethod method)

    addJavascriptInterface被调用时,会触发此方法。
    JavaContext 上下文

    需要注意的一些方法

    • 获取项目信息
      Project project = context.getMainProject();

    • 获取项目build.gradle中配置的minSdkVersion
      int minSdk= project.getMinSdk();
      以上判断如果minSDK大于17则不显示提示

    • JavaEvaluator
      求值类
      JavaEvaluator evaluator = context.getEvaluator();

    接下来判断调用addJavascriptInterface的对象是不是Android系统提供的WebView

    public boolean methodMatches(PsiMethod method,String className, boolean allowInherit,String... argumentTypes)

    method
    visitMethod中的method

    className
    addJavascriptInterface的类名如android.webkit.WebView

    allowInherit
    是否支持指定类的子类校验,比如WebView的子类

    argumentTypes
    指定方法中参数的类型
    public void addJavascriptInterface(Object object, String name)
    所以上面第一个参数为TYPE_OBJECT和TYPE_STRING

    创建提示类Issue

    Issue类提供了工厂方法创建issue
    public static Issue create(String id,String briefDescription,String
    explanation,Category category,int priority, Severity
    severity,Implementation implementation)

    • id Issue的自定义名字,如: AddJavascriptInterfaceLogUtilsNotUsed

    • briefDescription ,explanation.描述性(不解释)

    • category 类型 如Category.USABILITY

    • priority 优先级(1-10)

    • severity 安全级别(Severity.ERROR报错)

    • implementation Issue的实现类,如 new Implementation( AddJavascriptInterfaceDetector.class, Scope.JAVA_FILE_SCOPE)),第一个参数为类名。

    发送报告

    Context(子类JavaContext,ClassContext)
    public void report(Issue issue,Location location,String message)

    • issue 用Issue.create创建的类
    • location位置 context.getNameLocation(node)
    • message 提示消息

    相关文章

      网友评论

          本文标题:Android Studio是如何实现AddJavascript

          本文链接:https://www.haomeiwen.com/subject/twjczttx.html