Android WebView和JavaScript交互

现在移动应用几乎都是 Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”和“Web App跨平台开发的优势”。
而hybrid的实现关键在于打通Java和JavaScript之间的交互。
在Android开发中我们是使用WebView控件来加载HTML页面的,WebView默认为我们提供了让Java和HTML页面中JavaScript脚本交互的能力。

1 Java调用JavaScript

java调用JavaScript非常简单,只需要执行下面代码即可。

mWebView.loadUrl("javascript:methodName(parameterValues)");

不过其中还需要注意几个细节,我们先来看个例子,然后再介绍需要注意的地方。

IDE:Android Studio

先写一个H5的页面test.html,把它放在了assets资源文件下




    java调用JavaScript





xml布局:




    

Activity代码:

public class MyWebView extends AppCompatActivity {
    private WebView mWebView;
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_web_view);
        mWebView = (WebView) findViewById(R.id.id_webview);
        mButton = (Button) findViewById(R.id.id_button);
        loadURL();
    }

    private void loadURL() {
        mWebView.setWebViewClient(new WebViewClient());//此方法可以在webview中打开链接而不会跳转到外部浏览器
        mWebView.setWebChromeClient(new WebChromeClient());//各种内容的渲染需要使用webviewChromClient去实现,比如alert()方法
        mWebView.loadUrl("file:///android_asset/test.html");
    }

    private void initEvents() {
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.loadUrl("javascript:alertMessage(\""+"Message"+"\")");//注意转义字符
            }
        });
    }

    //重写onKeyDown,当浏览网页,WebView可以后退时执行后退操作。
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
            mWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

需要注意的是setWebViewClient(new WebViewClient())和setWebChromeClient(new WebChromeClient())方法。

  • setWebViewClient(new WebViewClient())可以在webview中打开链接而不会跳转到外部浏览器
  • setWebChromeClient(new WebChromeClient())方法可以给WebView设置一个WebChromeClient,各种内容的渲染需要使用webviewChromClient去实现,比如alert()方法,如果这个方法没写不会有alert()方法的效果。
Android WebView和JavaScript交互_第1张图片
01.jpg

点击按钮之后效果

Android WebView和JavaScript交互_第2张图片
02.jpg

2 JavaScript调用Java

WebView提供了一个名为WebSettings的工具类实现让Webview中的JavaScript脚本调用android应用的Java方法,实现方式很简单。

  • 调用与WebView关联的WebSettings实例的setJavaScriptEnabled方法使能调用的功能
  • 调用WebView的addJavaScriptInterface方法将应用中的Java对象暴露给JavaScript
  • 在JavaScript脚本中调用暴露的Java对象的方法

增加H5页面代码




    h5



    
    






我们新建提供给JavaScript调用的Java类javaObject

public class javaObject {
    private Context context;
    private final String TAG = "javaObjectLog";

    public javaObject(Context context) {
        this.context = context;
    }
    
    public void printLog(String mes){
        Log.i(TAG, mes);
    }

    
    public void showToast(){
        Toast.makeText(context, "Toast", Toast.LENGTH_SHORT).show();
    }
}

增加Activity代码

public class MyWebView extends AppCompatActivity {
    private WebView mWebView;
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_web_view);
        mWebView = (WebView) findViewById(R.id.id_webview);
        mButton = (Button) findViewById(R.id.id_button);
        loadURL();
        initEvents();
    }

    private void initEvents() {
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.loadUrl("javascript:alertMessage(\""+"Message"+"\")");
            }
        });
    }

    private void loadURL() {
        mWebView.setWebViewClient(new WebViewClient());//此方法可以在webview中打开链接而不会跳转到外部浏览器
        mWebView.setWebChromeClient(new WebChromeClient());//各种内容的渲染需要使用webviewChromClient去实现,比如alert()方法
        WebSettings webSettings = mWebView.getSettings();//
        webSettings.setJavaScriptEnabled(true);//
        mWebView.loadUrl("file:///android_asset/test.html");

        mWebView.addJavascriptInterface(new javaObject(this), "javaObject");//把javaObject类对象暴露给JavaScript
    }


    //重写onKeyDown,当浏览网页,WebView可以后退时执行后退操作。
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
            mWebView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

Android WebView和JavaScript交互_第3张图片
03.jpg

这种方法是官方提供的,但是却存在极大地安全隐患,所以从Android 4.2开始,Google就修复了这个漏洞,所以如果你测试机是4.2以上你会发现并没有成功调用暴露的方法。我们想要安全的使用上面的方法,唯一需要改动的就是对暴露给JavaScript调用的方法添加@JavascriptInterface注解。修改如下:

public class javaObject {
    private Context context;
    private final String TAG = "javaObjectLog";

    public javaObject(Context context) {
        this.context = context;
    }
    @JavascriptInterface
    public void printLog(String mes){
        Log.i(TAG, mes);
    }

    @JavascriptInterface
    public void showToast(){
        Toast.makeText(context, "Toast", Toast.LENGTH_SHORT).show();
    }
}

输出结果

Android WebView和JavaScript交互_第4张图片
04.jpg
05.png

你可能感兴趣的:(Android WebView和JavaScript交互)