Android webview 交互 封装

创建webview

// 这个不用说
this.getSettings().setJavaScriptEnabled(true);
// 这个解决跨域的问题
this.getSettings().setAllowFileAccessFromFileURLs(true);
this.setWebViewClient(new MyWebViewClient());
this.setWebChromeClient(new MyWebChromeClient());
// 这个是js调用Android方法的声明,第一个参数是类对象(也就是放Android哪个方法要被js调用的类,第二个参数可以自定义)
this.addJavascriptInterface(map.getCallback(), "Android");

开发过程中,这个onConsoleMessage这个很重要,监听js中的console.log的打印信息,因为无法debug

class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            // 监听js的alert打印  警告消息框
            FMLog.li("alert---" + url + message + result.toString());
            return super.onJsAlert(view, url, message, result);
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
                                  JsPromptResult result) {
            // 输入消息框
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
            // 确认消息框
            return true;
        }

        @RequiresApi(api = Build.VERSION_CODES.FROYO)
        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
            // 监听console打印
            ConsoleMessage.MessageLevel messageLevel = consoleMessage.messageLevel();
            if (messageLevel == ConsoleMessage.MessageLevel.ERROR) {
                FMLog.le("error", "linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message());
            } else if (messageLevel == ConsoleMessage.MessageLevel.LOG) {
                FMLog.li("console---" + "linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message() + ";level:" + consoleMessage.messageLevel());
            } else if (messageLevel == ConsoleMessage.MessageLevel.WARNING) {
                FMLog.lw("FMMapSdk_waring:",
                        "linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message() + ";" +
                                "level:" + consoleMessage.messageLevel());
            } else {
                FMLog.li("linenumber:" + consoleMessage.lineNumber() + ";message:" + consoleMessage.message() + ";" +
                        "level:" + consoleMessage.messageLevel());
            }
            return true;
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            FMLog.li("pro---" + newProgress + "");
        }
    }

html中的js方法,一定是要在onPageFinished这个回调之后才可以调用,否则会报错!!!

html中的js方法,一定是要在onPageFinished这个回调之后才可以调用,否则会报错!!!

html中的js方法,一定是要在onPageFinished这个回调之后才可以调用,否则会报错!!!

。无数遍

onReceivedError可以监听你方法调用错误的log打印

class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            FMLog.li("url---" + url);
            view.loadUrl(url);
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            loadMap(map.getFMLoadOption());
            FMLog.li("onPageFinished---" + "加载完成");
        }


        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            FMLog.li("onPageStarted---" + "开始加载");
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                FMLog.li("onReceivedError---" + request.getUrl().toString() + "--error:" + error);
            } else {
                FMLog.li("onReceivedError---" + "--error:" + view.getUrl());
            }
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            FMLog.li("onReceivedError---" + "errorCode:" + errorCode + "description:" + description + "failingUrl:" + failingUrl);
        }
    }

Android 调用 js

两个方式

this.evaluateJavascript("javascript:method()", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                
            }
        });
this.loadUrl("javascript:" + "loadMap('" + option + "')");

第一个是Android5.0之后使用,带返回值,但是这个不是同步返回;

第二个不带返回值,参数一版用一个json.toString();方便传递更多的参数

这样就可以封装通用的方式进行调用

/**
     * 通用方法
     *
     * @param method 方法名
     * @param object 参数
     */
    private void jsMethod(String method, Object object) {
        
        this.mView.loadUrl(mView.JSMethodHead + "" + method + "(" + object + ")");
    }

    private void jsMethod(String method) {
        
        this.mView.loadUrl(mView.JSMethodHead + "" + method + "()");
    }

    private void jsMethodCallBack(final String method, Object object, final FMJsMethodListener listener) {
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            this.mView.evaluateJavascript(mView.JSMethodHead + method + "(" + object + ")",
                    new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    listener.recive(method, value);
                }
            });
        }
    }

    private void jsMethodCallBack(final String method, final FMJsMethodListener listener) {
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            this.mView.evaluateJavascript(mView.JSMethodHead + method + "()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    listener.recive(method, value);
                }
            });
        }
    }

js 调用 Android 

Android这边声明的类在初始化那已经说过了,创建一个类

class FMMapCallBack {

    private final Handler handler;

    FMMapCallBack(Handler handler) {
        this.handler = handler;
    }

    @JavascriptInterface
    public void loadSuccess(String json) {
        Message message = handler.obtainMessage();
        message.what = 1;
        message.obj = json;
        handler.sendMessage(message);
    }

    @JavascriptInterface
    public void loadFailed(String error) {
        Message message = handler.obtainMessage();
        message.what = 0;
        message.obj = error;
        handler.sendMessage(message);
    }

    @JavascriptInterface
    public void JsCallBack(String json){
        try {
            JSONObject obj = new JSONObject(json);
            String name = obj.getString("name");
            Object value = obj.get("value");
            switch (name) {

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

js 这边可以通过初始化的自定义关键字进行调用

 window.Android.loadSuccess(JSON.stringify(json));

你发现我再callback类中使用了handler,那是因为js调用Android不是同步,回调方法执行在js thread线程中

 

 

发布了75 篇原创文章 · 获赞 12 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/androidwubo/article/details/105044509