Android 混合开发phonegap(Cordova)下,实现web开发中的Js和Java互相调用的功能

1: 本机混合开发Phonegap的配置,如下:
phonegap 版本: 6.4.6
Cordova 版本: 6.5.0

图片.png

2: 创建项目
命令:

$ cordova create hello com.example.hello HelloWorld  (后两个分拨是项目名称和包名)
$ cd hello 
$ cordova platform add android --save
图片.png

生成的android 项目目录:

图片.png

然后导入Platforms文件夹里面的android项目,结构如下:

Paste_Image.png

下面开始实现H5和android的数据传递:

一:以H5的js为起点,实现js调用android,android返回数据js

1: index.html

加入内容:

<div class="title">H5demo</div>
        <br/><br/>
        <div class="lastparent">
            <p class="tip">结果: </p>
            <br/>
            <textarea rows="10" cols="25" id="result" class="content">在这里会收到结果...</textarea>
            <br/><br/><br/>
            <button class="btn" onclick="addToCal();">点击获取数据</button>
            <br/><br/>
        </div>
device-2017-03-28-135937.png

2: index.css

加入内容:

.title{
    font-size:20px;
    background-color:#3F51B5;
    color:white;
    padding:15px 10px 15px 10px;//上,右,下,左
}

.btn{
    width:120px;
    height:40px;
    font-size:16px;
}

.content{
    font-size:20px;
}

.tip{
    font-size:20px;
}

.lastparent{
    margin: auto;
    text-align: center;
}
device-2017-03-28-135609.png

3.index.js

加入内容:

//给H5页面中的扫描按钮调用
            function addToCal() {
                var title = "PhoneGap Day";
                //js回调
                var success = function(message) {
                    //alert("Success");
                    //改变内容
                    var result = document.getElementById("result");
                    result.innerHTML = message;
                };
                var error = function(message) {
                    alert("Oopsie! " + message);
                };
                calendarPlugin.createEvent(title, success, error);
            }
            //java直接加载js方法的调用
            function javaCalljs(lastmessage){
                //alert("java调用js"+lastmessage);
                var result = document.getElementById("result");
                result.innerHTML = lastmessage;
            }

var calendarPlugin = {
    createEvent: function(title, successCallback, errorCallback) {
        cordova.exec(
            successCallback, // success callback function
            errorCallback, // error callback function
            'MyPlugin', // mapped to our native Java class called "CalendarPlugin"
            'addAnroidEntry', // with this action name
            [{                  // and this array of custom arguments to create our entry
                "title": title
            }]
        );
     }

说明:点击按钮addToCAL , 调用插件calendarPlugin的方法createEvent, 然后触发 cordova.exec, 然后调用插件Myplugin的方法exec, 这样就实现了js调用android,android返回数据js。

4: 插件Myplugin

该类是自定义的插件,来实现js调用android的功能,最终调用exec()方法

@Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext)
            throws JSONException {
        try {
            if (ACTION_ADD_ANDROID_ENTRY.equals(action)) {
                //调用android的dialog
                startDialog(callbackContext);
                return true;
            }
            callbackContext.error("Invalid action");
            return false;
        } catch(Exception e) {
            System.err.println("Exception: " + e.getMessage());
            callbackContext.error(e.getMessage());
            return false;
        }
    }


/**
     * 通过js调用java,实现js触发android功能
     * @param callbackContext
     */
    private void startDialog(final CallbackContext callbackContext) {
        new AlertDialog.Builder(mActivity)
                .setTitle("提示")
                .setMessage("接收到js的触发")
                .setPositiveButton("确定", new Dialog.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        callbackToJs(callbackContext);
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        loadJsFunction();
                        dialog.dismiss();
                    }
                })
                .setCancelable(false)
                .show();
    }

点击确定按钮:由js触发插件的方法execute,然后由callbackContext回调函数,给数据js

/**
     * 由js触发插件的方法execute,然后由callbackContext回调函数,给数据js
     *
     * @param callbackContext
     */
    private void callbackToJs(final CallbackContext callbackContext){
        callbackContext.success("确定按钮回复: 收到了,谢谢!");
    }

二:以android的java为起点,实现java代码调用js

上面dialog,点击了取消按钮 : webview.loadurl方法可以直接调用js的功能

/**
     * 不通过方法execute, java自己调用js的方法
     *
     * webview.loadurl需要工作的在UI主线程
     */
    private void loadJsFunction(){

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(mWebView != null){
                    mWebView.loadUrl("javascript:"+ "javaCalljs(\'"+ "取消按钮回复: java自己调用js方法" +"\')");
                }else{
                    Log.d(TAG, "webViewCallJavascript: mwebview is null !");
                }
            }
        });
    }
device-2017-03-28-141311.png

到这里基于phonegap(cordova)的混合开发demo,实现js和andorid之间的触发数据传递就完成了!

坑1:webview,退出时,报错了E/webview: java.lang.Throwable: Error: WebView.destroy() called while still attached!

解决:

 @Override
    public void onDestroy() {

        //解除webview绑定在父布局的情况,不用时,需要释放
        ViewGroup viewGroup = (ViewGroup)mActivity.findViewById(android.R.id.content);
        SystemWebView webView = (SystemWebView) viewGroup.getChildAt(0);
        viewGroup.removeView(webView);
        webView.removeAllViews();

        mWebView = null;
        super.onDestroy();
    }
坑2:SystemWebChromeClient: file:///android_asset/www/index.html: Line 54 : Refused to execute inline event handler because it violates the following Content Security Policy directive: "default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'". Either the 'unsafe-inli.........

解决: index.html中, 以<meta http-equiv="Content-Security-Policy"修改如下:

<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src *" />

demo地址: https://github.com/George-Soros/H5WebAppDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容