Android WebView Java和JavaScript的交互

现在的APP,大多是NA+H5的,也就是集合了Native APP和Web APP的优点,既保证了用户体验,又使得APP在一定程度上具备动态更新的能力,同时又利于跨平台开发,减少了人力成本。

一、Java调用JavaScript

Java调用JS很简单,

mWebView.loadUrl("javascript:toast()");

让WebView加载本地html,并调用JS中的toast函数,
本地的html如下

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    function toast() {
        alert("xxxx");
    }
</script>
</body>
</html>

Java代码如下

public class MyActivity extends Activity {  
    private WebView mWebView;  
    private Button mBtn;  

    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  

        mWebView = (WebView) findViewById(R.id.webview);  
        mBtn = (Button) findViewById(R.id.btn);  

        WebSettings webSettings = mWebView.getSettings();  
        webSettings.setJavaScriptEnabled(true);
        mWebView.loadUrl("file:///android_asset/web.html");
        mBtn.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                mWebView.loadUrl("javascript:toast()");  
            }  
        });  
     }  
}  

二、JavaScript调用Java

需要三步
(1)setJavaScriptEnabled来启用JS
(2)对暴露给JS调用的方法增加@JavascriptInterface注解
(3)在JS中调用Java暴露的方法

以从Java获取WebView加载的html页面内容为例。当WebView把html加载完成后,JS调用Java暴露的方法,把html页面的内容回吐给Java。

代码如下:

public class WebViewTestActivity extends Activity {

    private static final String TAG = "WebViewTestActivity";
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview_test_layout);

        initView();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initView() {
        webView = (WebView) findViewById(R.id.webView);
        //启用支持javascript
        webView.getSettings().setJavaScriptEnabled(true);
        webView.addJavascriptInterface(new JSBridge(), "android");
        // 必须在主线程中
        webView.loadUrl("http://hello2mao.github.io/pages/about.html");
        webView.setWebViewClient(new WebViewClient() {
            // 依然在webview打开新页面
            // 拦截 url 跳转,在里边添加点击链接跳转或者操作
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            // 在WebView开始加载网页时调用
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            // 在结束加载网页时会回调
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // 通过内部类定义的方法获取html页面加载的内容,这个需要添加在webview加载完成后的回调中
                view.loadUrl("javascript:window.android.show(document.body.innerHTML);");
            }

        });
    }

    public class JSBridge {
        @JavascriptInterface
        public void show(String data) {
            // 这里的data就webview加载的内容,即使页面跳转页都可以获取到,这样就可以做自己的处理了
            Log.d("LOG_TAG", data);
            saveFile("<html>" + data + "</html>");
        }
    }

    private static void saveFile(String str) {
        String filePath = null;
        boolean hasSDCard = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (hasSDCard) { // SD卡根目录的hello.text
            filePath = Environment.getExternalStorageDirectory().toString() + File.separator + "hello.txt";
        } else  // 系统下载缓存根目录的hello.text
            filePath = Environment.getDownloadCacheDirectory().toString() + File.separator + "hello.txt";

        try {
            File file = new File(filePath);
            if (!file.exists()) {
                File dir = new File(file.getParent());
                dir.mkdirs();
                file.createNewFile();
            }
            FileOutputStream outStream = new FileOutputStream(file);
            outStream.write(str.getBytes());
            outStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页