惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - Rickel

数据库镜像的配置 查看SQL Server中某数据库下每个表占用的空间大小 about WBS sql server 2005 压缩实例下所有数据库文件及日志文件 语句 TFS服务器及服务帐号迁域的处理 [西安招聘] 微软西安分公司 招聘.NET软件工程师,MOSS开发工程师 SQL清除数据库日志方法 JavaScript 中的Key 事件区别 ASP.NET URL Rewrite. URL重写 生成高品质的缩略图 Apache Error:(OS 10048)Only one usage of each socket address is normally permitted. 页面响应自定义控件的事件 推荐大家看 《亵渎》 断字处理 break-word I'm Back 部署带Crystal Reports的Web应用程序 - Rickel 用C#读取Excel文件:从指定单元格开始向右向下读取数据 Well-formed AssemblyInfo.cs 毕业一周年纪念
在webView 中使用JS 调用 Android / IOS的函数 Function
Rickel · 2014-12-30 · via 博客园 - Rickel

最近做一个项目,混合了NativeCode 和 HTML,为了便于JS 调用App的一些方法,统一封装一个Js方法,记录如下

Android 端首先要再WebView中允许JS的调用

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new WebAppInterface(this), "JsAndroid");

IOS端使用的是一个开源库 EasyJsWebView,在IOS端引用即可

JS代码:

function callApp(method) {
        var args = [].slice.call(arguments).splice(1);
        var s = "";
        if (/android/i.test(navigator.userAgent)) {//安卓
            s = window["JsAndroid"][method].apply(window.JsAndroid, args);
        }
        if (/ipad|iphone|mac/i.test(navigator.userAgent)) {//ios
            s = window["JsIOS"][method].apply(this, args);
        }
        return s;
    }

//与IOS交互的方法
window.EasyJS = {
    __callbacks: {},
    
    invokeCallback: function (cbId, removeAfterExecute) {
        var args = Array.prototype.slice.call(arguments).splice(2);

        for (var i = 0, l = args.length; i < l; i++) {
            args[i] = decodeURIComponent(args[i]);
        }

        var cb = EasyJS.__callbacks[cbId];
        if (removeAfterExecute) {
            EasyJS.__callbacks[cbId] = undefined;
        }
        return cb.apply(null, args);
    },

    call: function (obj, functionName, args) {
        var formattedArgs = [];
        for (var i = 0, l = args.length; i < l; i++) {
            if (typeof args[i] == "function") {
                formattedArgs.push("f");
                var cbId = "__cb" + (+new Date);
                EasyJS.__callbacks[cbId] = args[i];
                formattedArgs.push(cbId);
            } else {
                formattedArgs.push("s");
                formattedArgs.push(encodeURIComponent(args[i]));
            }
        }

        var argStr = (formattedArgs.length > 0 ? ":" + encodeURIComponent(formattedArgs.join(":")) : "");

        var iframe = document.createElement("IFRAME");
        iframe.setAttribute("src", "easy-js:" + obj + ":" + encodeURIComponent(functionName) + argStr);
        document.documentElement.appendChild(iframe);
        iframe.parentNode.removeChild(iframe);
        iframe = null;

        var ret = EasyJS.retValue;
        EasyJS.retValue = undefined;

        if (ret) {
            return decodeURIComponent(ret);
        }
    },

    inject: function (obj, methods) {
        alert(obj);
        window[obj] = {};
        var jsObj = window[obj];
        for (var i = 0, l = methods.length; i < l; i++) {
            (function () {
                var method = methods[i];
                var jsMethod = method.replace(new RegExp(":", "g"), "");
                jsObj[jsMethod] = function () {
                    alert("qq");
                    return EasyJS.call(obj, method, Array.prototype.slice.call(arguments));
                };
            })();
        }
    }
};

说明一下,一开始调用Android也是采用window["JsAndroid"][method].apply(this,args),这样的话,就完全一致了。但是在调试的时候发现这种方式无法正常调用,google后发现是由于this的的影响域导致的,需要指明查找域。 参考

记录一下!