Java代码和js代码相互调用

2018-09-18  本文已影响0人  飞奔吧牛牛

开发时遇到了这样的需求:
1.网页自动设置Activity中的Title标题名,
2.Activity中有定位功能,得到定位结果后要回传给网页。
其实就是js代码和java代码的相互调用,
下面我们就来实现这样的需求。

设置webView,给webView添加js接口

 mWebView = (WebView) findViewById(R.id.webview);
 mWebView.getSettings().setJavaScriptEnabled(true);
 mWebView.getSettings().setSupportZoom(true);
 WebSettings webSetting = mWebView.getSettings();
 webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
 //JSInte类中的方法会被js代码调用。调用方式为,js.fun();这里的“js”就是第二个参数。
 mWebView.addJavascriptInterface(new JSInte(this), "js");
下面是JSInte类,该类中被js调用的方法必须添加@JavascriptInterface注解。而且必须用public修饰。
public class JSInte{

    private Activity activity;

    public JSInte(Activity activity) {
        this.activity = activity;
    }

    //js调用java:js.goBack();
    @JavascriptInterface
    public void goBack() {
        activity.onBackPressed();
    }

    @JavascriptInterface
    public void setTitle(String title) {
        //给Activity设置Title
        ((BaseTitleActivity) activity).getTitleBar().setTitleText(title);
    }

    //获取经纬度
    @JavascriptInterface
    public String getLocation() {
       if (activity instanceof LocationAble) {
            return ((LocationAble) activity).getLocation();
        } else {
            return null;
        }
    }
}

setTitle()方法中,将activity强转为父类,获取titleBar,设置title。
goBack()方法则和getLocation()方法在Activity中为:
注意:让activity实现LocationAble接口,判断activity instanceof LocationAble,是因为如果有Activity1和Activity2都需要被网页调用getLocation方法,则无法判断应将该activity强转为哪个。使用LocationAble接口就可以直接调用接口中的方法即可。

//这个接口很简单只有一个getLocation()方法
public interface LocationAble {

    String getLocation();
}

    //当webView中的网页可以返回时调用网页的返回。否则,结束activity。
    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
        } else {
            finish();
        }
    }
    
    //这个需要用到定位当有定位结果时,返回定位结果中的经纬度,没有则返回null。
    @Override
    public String getLocation() {
        if (mLocation != null) {
            double latitude = mLocation.getLatitude();
            double longitude = mLocation.getLongitude();
            return longitude + "_" + latitude;
        } else {
            return null;
        }
    }
如果网页调用Java的getLocation方法时,如果这时没有定位成功,网页就获取不到经纬度。有两个方法解决这个问题:1.网页开循环,每隔一段时间就调用一下getLocation(),有返回结果后停止循环。(显然这种方法很不好)2.本地定位成功后,主动调用网页的方法,将经纬度传递过去。
BDAbstractLocationListener listener = new BDAbstractLocationListener() {

        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            mLocation = bdLocation;
            double latitude = mLocation.getLatitude();
            double longitude = mLocation.getLongitude();
            String result = longitude + "_" + latitude;
            //这里的acceptLocation方法就是网页上的js方法,接收一个参数
            mWebView.loadUrl("javascript:acceptLocation('" + result + "')");
            //如果是两个参数写法是这样,之前由于中间逗号两边没加单引号','导致调用不成功
            mWebView.loadUrl("javascript:acceptLocation('" + longitude + "','" + latitude + "')");            
        }
    };

最后,JsInte类需要在混淆文件中配置,否则打包后js无法调用Java方法

-keep public class com.app.application.ui.js.JSInte{
    public <methods>;
}
上一篇 下一篇

猜你喜欢

热点阅读