HTML5,js与Android native通信

概述

何为h5,js与Android通信?其实说白了就是js调用Android本地方法和Android本地调用js方法之间的一个过程。这篇文章主要是讲述一个简单的通信方式,至于通信间数据的协议我用的是jsonRpc,在这里不做过多的描述,不懂的可以自行查阅,因为大多数人通信时不会用这个。

webview设置

这个应该不是问题,大概的设置就是一些基本项,这里贴一下代码,没有什么特殊的。

private void initWebView() {
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDatabaseEnabled(true);
//        webSettings.setDatabasePath("/data/data/" + Envi.appContext.getPackageName() + "/localstorage/");
        webSettings.setDomStorageEnabled(true);
        webSettings.setSavePassword(false);
        webSettings.setSaveFormData(true);
        webSettings.setSupportZoom(false);
        webSettings.setGeolocationEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setAppCacheEnabled(true);
        webSettings.setAllowFileAccess(true);
//        webSettings.setAppCacheMaxSize(100 * 1024 * 1024);
//        webSettings.setAppCachePath("/data/data/" + Envi.appContext.getPackageName() + "/cache/");
//        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);

//        String userAgent = webSettings.getUserAgentString();
//        userAgent = userAgent + "  ganji_" + Envi.customerId + "_" + Envi.versionName;
//        webSettings.setUserAgentString(userAgent);
    }

这里可以根据需求注释/打开某些设置。

webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                return super.shouldOverrideUrlLoading(view, url);
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Log.e("html5", "webview receive error: " + description);
                super.onReceivedError(view, errorCode, description, failingUrl);
                mWebViewReceivedError = true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                mPageLoadFinished = true;
                if (mWebViewReceivedError) {//TODO network is ok?
                    webView.post(new Runnable() {
                        @Override
                        public void run() {
                            webView.setVisibility(View.GONE);
//                            mLoadFailContainer.setVisibility(View.VISIBLE);
                        }
                    });
                }
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }
        });

        webView.setWebChromeClient(new WebChromeClient() {

            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
                callback.invoke(origin, true, false);
                super.onGeolocationPermissionsShowPrompt(origin, callback);
            }

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return true;
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                return true;
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                return true;
            }

            @Override
            public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota,
                                                WebStorage.QuotaUpdater quotaUpdater) {
                quotaUpdater.updateQuota(estimatedDatabaseSize * 2);
            }

            @Override
            public void onReachedMaxAppCacheSize(long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater) {
                quotaUpdater.updateQuota(requiredStorage * 2);
            }

        });

这里没什么参考的必要,主要是对两个Client的设置,根据你的需求来。

native 调用js方法

下面说重点,js调用native方法,首先,我贴下我js的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script>
        function showInfo(str)
        {
            document.getElementById("info").innerHTML=str;
        }
    </script>
</head>
    <body>
        从Android传来的值是:<span id="info"> </span>
        <br>
        <a href="#" onclick="window.GJNativeAPI.callAndroid(‘I am come from android.‘)">
        call Android from javascript
        </a>
    </body>
</html>

这里比较重要的是,要定义好function方法的名字,native调用时就是根据这个调用的。我在一个button点击事件里调用它:

btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调用此语句,调用js里的方法
                webView.loadUrl("javascript:showInfo(‘hello js‘)");
            }
        });

这样就挖成了一个native调用js方法。重点是js的方法名,和Android的javascript:后的方法名一致。

js调用native方法

这个还要对webview做一个额外的设置:

mWebView.addJavascriptInterface(new GJNativeAPI(), "GJNativeAPI");

然后我们看看这个GJNativeAPI是什么东东:

/**
     * 供 js 调用的本地对象
     */
    public class GJNativeAPI {

        /**
         * js 调用该方法发起 rpc 调用,或者返回 rpc 响应
         */
        @JavascriptInterface
        public void callAndroid(final String str) {
            System.out.print("!!!!"+str);
            activity.setText(str);
        }
    }

这是我自定义的一个内部类,它里面有一个callAndroid方法,注意上边一定要写上@JavascriptInterface,不然某些版本的sdk上是有错的。

然后我们回头看js文件:

        <a href="#" onclick="window.GJNativeAPI.callAndroid(‘I am come from android.‘)">

window是调用native方法时要加的,GJNativeAPI是我们的那个自定义内部类,callAndroid是我们写的那个方法,这样就完成了调用。

注意

如果你这么写:

btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调用此语句,可以调用js里调用Android相关的方法,最终还是回到Android native                webView.loadUrl("javascript:window.GJNativeAPI.callAndroid(‘hello js‘)");
            }
});

你会发现,你在native调用的,又回到了native,就是在js上走了一圈。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-04 17:18:04

HTML5,js与Android native通信的相关文章

React-Native系列Android——Native与Javascript通信原理(二)

前一篇博客分析了Native端向Javascript端通信的全流程,这次来研究下Javascript端向Native端通信的全流程,与前篇恰好构成一个基本完整的通信机制. 本篇博客内容与前篇联系较大,有些分析过的东西这次就直接拿来用了,不再赘述,所以希望阅读这篇文章之前先熟悉下前篇: React-Native系列Android--Native与Javascript通信原理(一) http://blog.csdn.net/MegatronKings/article/details/51114278

React-Native系列Android——Native与Javascript通信原理(三)

前面两篇博客,详细分析了Native与Javascript通信的过程,可以满足绝大部分场景下Native和Javascript的相互调用,但是仍然有不健全的情况. 比如Javascript层要实时获取Native的一些状态,就需要Native被动地向Javascript层通信了.这个过程区别于通信第一篇中Native主动向Javascript层通信,本篇博客就来研究下这样一个被动回调的过程! 在阅读本篇博客前,希望能回顾下前两篇. React-Native系列Android--Native与Ja

PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码

PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码 看看新闻网>看引擎>开源产品 0人收藏此文章, 发表于8小时前(2013-09-06 00:39) , 已有13次阅读 ,共0个评论 依照我一惯得套路,我会先说一点废话. PhoneGap和Cordova什么关系?为什么有的地方叫Cordova而有的地方叫PhoneGap ?PhoneGap是一款HTML5平台.通过它,开发商能够使用HTML.CSS及JavaScript来开发本地移动应用程序.因此,眼下开

[IOS_HTML5]各种JS框架介绍--用HTML5/CSS3/JS开发Android/IOS应用

现在人人都想成为安卓/IOS应用开发工程师.其实,安卓/IOS应用可以用很多种语言来实现.由于我们前端开发工程师,对HTML5/CSS/JavaScript的网络编程已经相当熟悉了.所以,今天大家将会认识到一些利用前端语言来开发安卓/IOS应用的工具. 在文章的末尾,也介绍了使用JAVA.C#.Lua以及AS3来开发安卓应用的工具. 希望大家都能找到适合自己的开发工具!祝大家开发安卓/IOS应用一切顺利! PhoneGap 开发语言: HTML, CSS, JavaScript 开发工具: Ph

Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败分析

Q:Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败? 在Android Native层调用Camera.h中的api实现一个截屏功能的应用时,发现通过gCamera->setListener(new ScreenCaptureListener())设置到Camera的mListener的用于接收Camera预览数据的回调函数没有被调用,导致截屏失败? 注: Camera类文件汇总: libcamera_client.so

WebView中Js与Android本地函数的相互调用

介绍 随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现. 既然要实现混合开发,那么Js与Android原生函数的相互调用就必不可少了.这里写了一个demo,实现点击html中的图片进行本地展示. 原理 1.Android调用js很简单,直接webView.loadUrl("javascript:JS中的方法名称()");即可. 2.js调用Android方法,需要使用WebView.

JS调用Android、Ios原生控件

在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时,提高代码质量,实现两者在网页端代码的统一. 首先我们先看一下Ios调用JS的方法实现: //无参调用 function SwiftCallJs1(){} //有参调用 function SwiftCallJs2(name, message){} 紧接着我们看一下Android调用JS的方法实现: /

HTML5+JS手机web开发之jQuery Mobile初涉

一.起始之语 我一直都是在PC上折腾网页的,这会儿怎么风向周边捣鼓起手机网页开发呢?原因是公司原先使用Java开发的产品,耗了不少人力财力,但是最后的效果却不怎么好.因为,Android系统一套东西,iPhone又是新的一套,折腾死人呐. 于是总监发狠,让我把手上的活都交出去,专心折腾web版的,看看最后效果如何. 加上我觊觎手机上的开发学习很久了,于是,一拍即合,搞起了手机开发方面的学习. 分享是很好的提高自身学习的方法.因为分享过程中梳理了所学,往往会有些意想不到的心得与收获.如此利人利已的

js 页面间的通信

目录 一.window对象的open方法 1.window对象 2.window对象的open方法 (1)window.open(URL,name,features,replace) (2)用window.open方法实现页面通信 3.window.showModalDialog (1)window.showModalDialog (2)window.showModelessDialog (3)兼容性 4.window的height和width (1)原生js的window.innerWidth