- 浏览: 505661 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (200)
- java基础 (30)
- ajax (19)
- 乱写 (5)
- groovy (2)
- db (8)
- gwt (0)
- jee (2)
- 我关注的开源 (1)
- RIA AIR (1)
- spring (11)
- lucene (0)
- 工具 (10)
- 百科 (2)
- linux (6)
- android (40)
- 移动开发 (21)
- 代码片断 (15)
- tomcat (1)
- css (1)
- html5 (2)
- jquery (2)
- playframework (3)
- web (2)
- nio (3)
- design (1)
- nosql (3)
- 日志 (12)
- mysql (4)
- 图表 (1)
- python (3)
- ruby (1)
- git (0)
- hibernate (1)
- springboot (1)
- guava (1)
- mybatis (0)
- 工作问题 (3)
- php (1)
最新评论
-
linzm1990:
踩了很多坑啊。。。。
hibernate @Nofound 与@ManyToOne fetch lazy的问题 -
Ccccrrrrrr:
...
转: Spring boot 文件上传 -
rmzdb:
兄弟,你这个东西,在ie内核的浏览器,貌似不识别 文件名
工作问题:http下载文件,中文文件名在firefox下乱码问题 -
107x:
问题解决了,谢谢!
工作问题:http下载文件,中文文件名在firefox下乱码问题 -
klxqljq:
额鹅鹅鹅
android布局实现头尾固定, 中间多余内容可以滚动
通过WebView在javascript里调用java 方法代码, 在java代码里执行javascript代码, 二者通过json进行数据交换
设置 WebView 小部件
将一个名为 browser 的 Activity 范围变量捆绑到了 WebView 控件。WebView 是一个相当复杂的类,可高度定制。例如,您需要设置几个类,以得到与 web 浏览器相关的预期函数。这是程序员必须投入一定精力来得到一些有用函数的地方之一。但是,此定制是没有限制的。对于此应用程序的目的来说,WebView 控件已经进行了最低限度的部署。
WebViewClient 提供用于捕获各种事件的钩子,这些事件包括页面加载开始和结束、表单重新提交、键盘截取以及程序员喜欢跟踪并操纵的很多其他事件。类似地,您需要 WebChromeClient 的一个实例,用于允许诸如非常有用的 alert() JavaScript 函数之类的函数。使用 WebSettings 来为控件启用 JavaScript。
连接 JavaScript 接口
下一步是启用 Activity 中的 Java 代码,以与 WebView 管理的 HTML 文件中的 JavaScript 代码交互。这是通过调用 addJavascriptInterface() 方法完成的,如 清单 4 所示。
该函数的参数是一个 Java 类的实例和一个名称空间标识符。例如,对于这个应用程序,您定义一个 calc 名称空间,并实现名为 CalculatorHandler 的类中的代码,如 清单 5 所示。
清单 5. CalculatorHandler 实现
在 JavaScript 环境中,通过 window.calc.methodname 语法访问 CalculatorHandler 的方法。例如,CalculatorHandler 实现一个名为 Info() 的方法,后者接受一个字符串参数并将之写到应用程序日志中。要从 JavaScript 环境访问此方法,可使用类似这样的语法:window.calc.Info("write this string to the application log!");。
基本了解了如何从 JavaScript 代码调用 Java 代码之后,我们再来看 清单 6 中的 index.html 文件,看各种方法是如何被调用的。
清单 6. WebView 控件中呈现(和执行)的 index.html
仔细研究一下 清单 6 末尾的按钮处理程序。基本上,这些按钮处理程序都调用 window.calc 名称空间中的方法,这些方法在 AndroidJSON.java 中的 CalculatorHandler 类中实现。
清单 5 和 清单 6 协同工作,演示了 JavaScript 环境中初始化的和 Java 源文件中实现的代码交互。但是如何从 Activity 代码中初始化一些您想要在 WebView 中发生的动作呢?
现在应该更深入地来看 Java 代码了。
插入 JavaScript 代码
从将一个数学公式传递到 JavaScript 代码进行计算这样一个任务开始。JavaScript 最伟大(也最危险)的特性之一是 eval() 函数。eval() 函数允许字符串代码的运行时计算。在本例中,您从 EditText 控件接受一个字符串并传递到 JavaScript 环境进行计算。具体来说,我们调用 清单 6 中的 PerformSimpleCalculation() 函数。
清单 7 包含 AndroidJSON.java 中的代码,它负责处理按钮选择。
清单 7. 从 Java 调用 PerformSimpleCalculation() JavaScript 函数
不管此方法有多少行,这里唯一要关注的是 browser.loadurl() 行,它传递一个格式字符串:javascript:<code to execute>。
此 JavaScript 代码被注入到 WebView 的当前页面并执行。这样,Java 代码就可以执行 WebView 中定义的 JavaScript 代码了。
在 Simple 例子中,传递了一个字符串。但是,当需要处理更复杂的结构时该怎么办呢?这就是 JSON 可派上用场的地方。清单 8 展示了 PerformComplexCalculation() 函数的调用,该函数参见 清单 6。
清单 8. 通过传递一个 JSON 对象调用更复杂的函数
研究一下 清单 6 中的 JavaScript 函数 PerformComplexCalculation。注意,传递进来的参数不是字符串,而是您自己创建的一个对象。
* operation - 要处理的函数或过程的名称
* arguments - 这是一个整数数组
对象只包含两个属性,但是完全可以更复杂,以满足更高的需求。在本例中,PerformComplexCalculation() JavaScript 函数支持两种不同的操作:addarray 和 multarray。当这些操作在调用时完成其工作时,通过调用函数 window.calc.setAnswer,将结果传递回 Java 代码。这里,您看到了 Java 和 JavaScript 代码之间的双向数据流。
在本例中,您传递了一个 JSON 对象,但是得到的一条经验是,在处理从 Java 代码返回来的 Java 字符串时,它有助于将它们转换成 JavaScript 字符串。这可以像本例中一样通过将值传递给 String 函数来做到:eval(String(formula));。
JavaScript eval() 函数使用 JavaScript 字符串。无需转换的话,eval 函数基本上不做任何事情。
对于一个稍微复杂一点的例子,鼓励您好好看一下 Dynamic 按钮在 WebView 中被选中时的代码段。
要完成代码例子,来看一下将一个字符串数组从 JavaScript 环境传递到 Java 环境。
交换 JSON 对象
示例应用程序 (index.html) 中的 JavaScript 代码将本地函数调用记录到一个名为 cmdHistory 的页面级别数组中。每次调用函数时,您都将一个新条目添加到该数组中。例如,当 dynamicfunction() 被调用时,一个新的字符串被存储:cmdHistory[cmdHistory.length] = "PerformCompleCalculation-dynamic";。
关于此方法,没有什么特别的地方;它只是一个在页面级别收集使用数据的例子。也许该数据存储在 Android 应用程序的数据库中会有用。此数据如何回到 Java 代码呢?
要发送字符串对象数组,您调用 JSON.stringify 函数,将数组作为参数传递进来。根据需要,stringify 函数可以允许定制一个复杂对象的特定属性如何被格式化。关于这是如何完成的更多信息,可以参考 json.org 中的解释
设置 WebView 小部件
// connect to our browser so we can manipulate it browser = (WebView) findViewById(R.id.calculator); // set a webview client to override the default functionality browser.setWebViewClient(new wvClient()); // get settings so we can config our WebView instance WebSettings settings = browser.getSettings(); // JavaScript? Of course! settings.setJavaScriptEnabled(true); // clear cache browser.clearCache(true); // this is necessary for "alert()" to work browser.setWebChromeClient(new WebChromeClient()); // add our custom functionality to the javascript environment browser.addJavascriptInterface(new CalculatorHandler(), "calc"); // uncomment this if you want to use the webview as an invisible calculator! //browser.setVisibility(View.INVISIBLE); // load a page to get things started browser.loadUrl("file:///android_asset/index.html"); // allows the control to receive focus // on some versions of Android the webview doesn't handle input focus properly // this seems to make things work with Android 2.1, but not 2.2 // browser.requestFocusFromTouch();
将一个名为 browser 的 Activity 范围变量捆绑到了 WebView 控件。WebView 是一个相当复杂的类,可高度定制。例如,您需要设置几个类,以得到与 web 浏览器相关的预期函数。这是程序员必须投入一定精力来得到一些有用函数的地方之一。但是,此定制是没有限制的。对于此应用程序的目的来说,WebView 控件已经进行了最低限度的部署。
WebViewClient 提供用于捕获各种事件的钩子,这些事件包括页面加载开始和结束、表单重新提交、键盘截取以及程序员喜欢跟踪并操纵的很多其他事件。类似地,您需要 WebChromeClient 的一个实例,用于允许诸如非常有用的 alert() JavaScript 函数之类的函数。使用 WebSettings 来为控件启用 JavaScript。
连接 JavaScript 接口
下一步是启用 Activity 中的 Java 代码,以与 WebView 管理的 HTML 文件中的 JavaScript 代码交互。这是通过调用 addJavascriptInterface() 方法完成的,如 清单 4 所示。
该函数的参数是一个 Java 类的实例和一个名称空间标识符。例如,对于这个应用程序,您定义一个 calc 名称空间,并实现名为 CalculatorHandler 的类中的代码,如 清单 5 所示。
清单 5. CalculatorHandler 实现
// Javascript handler final class CalculatorHandler { private int iterations = 0; // write to LogCat (Info) public void Info(String str) { iterations++; Log.i("Calc",str); } // write to LogCat (Error) public void Error(String str) { iterations++; Log.e("Calc",str); } // sample to retrieve a custom - written function with the details provided // by the Android native application code public String GetSomeFunction() { iterations++; return "var q = 6;function dynamicFunc(v) { return v + q; }"; } // Kill the app public void EndApp() { iterations++; finish(); } public void setAnswer(String a) { iterations++; Log.i(tag,"Answer [" + a + "]"); } public int getIterations() { return iterations; } public void SendHistory(String s) { Log.i("Calc","SendHistory" + s); try { JSONArray ja = new JSONArray(s); for (int i=0;i<ja.length();i++) { Log.i("Calc","History entry #" + (i+1) + " is [" + ja.getString(i)+ "]"); } } catch (Exception ee) { Log.e("Calc",ee.getMessage()); } } }
在 JavaScript 环境中,通过 window.calc.methodname 语法访问 CalculatorHandler 的方法。例如,CalculatorHandler 实现一个名为 Info() 的方法,后者接受一个字符串参数并将之写到应用程序日志中。要从 JavaScript 环境访问此方法,可使用类似这样的语法:window.calc.Info("write this string to the application log!");。
基本了解了如何从 JavaScript 代码调用 Java 代码之后,我们再来看 清单 6 中的 index.html 文件,看各种方法是如何被调用的。
清单 6. WebView 控件中呈现(和执行)的 index.html
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=0.25, user-scalable=yes" /> <title>Android to JavaScript with JSON</title> </head> <script language="JavaScript"> var cmdHistory = new Array(); function startup() { try { window.calc.Info("Starting up...."); cmdHistory[cmdHistory.length] = "startup"; } catch (ee) { } } function PerformSimpleCalculation(formula) { try { cmdHistory[cmdHistory.length] = "PerformSimpleCalculation"; var answer = eval(String(formula)); document.getElementById('data').value = answer; window.calc.setAnswer(answer); } catch (ee) { window.calc.Error(ee); } } function PerformComplexCalculation(andmethod) { try { /* * argument to this function is a single object with 2 "members or properties" * operation: this is a string naming what we want the function to do. * array of arguments: this is an array of integers * */ //alert(andmethod.operation); //alert(andmethod.arguments.length); if (andmethod.operation == "addarray") { cmdHistory[cmdHistory.length] = "PerformCompleCalculation-addarray"; var i; var result = 0; for (i=0;i<andmethod.arguments.length;i++) { result += andmethod.arguments[i]; } document.getElementById('data').value = result; window.calc.setAnswer(result); } if (andmethod.operation == "multarray") { cmdHistory[cmdHistory.length] = "PerformCompleCalculation-multarray"; var i; var result = 1; for (i=0;i<andmethod.arguments.length;i++) { result *= andmethod.arguments[i]; } document.getElementById('data').value = result; window.calc.setAnswer(result); } } catch (ee) { window.calc.Error(ee); } } function dynamicfunction() { try { cmdHistory[cmdHistory.length] = "PerformCompleCalculation-dynamic"; eval(String(window.calc.GetSomeFunction())); var result = dynamicFunc(parseInt(document.getElementById('data').value)); document.getElementById('data').value = result; }catch (ee) { alert(ee); } } </script> <body > <center> <h3>Running in Web View :)</h3> this is some sample text here <br /> <input type="text" id="data" value="starting value"><br /> <button onclick="window.calc.Info(document.getElementById('data').value);">Log Info</button> <button onclick="window.calc.Error(document.getElementById('data').value);">Log Error</button><br /> <button onclick="dynamicfunction();">Dynamic</button> <button onclick="alert(String(window.calc.getIterations()));">How Many Calls</button> <button onclick="window.calc.SendHistory(JSON.stringify(cmdHistory));"> History</button> <button onclick="if (window.confirm('End App?')) window.calc.EndApp();">Kill This App</button><br /> </center> </body> </html>
仔细研究一下 清单 6 末尾的按钮处理程序。基本上,这些按钮处理程序都调用 window.calc 名称空间中的方法,这些方法在 AndroidJSON.java 中的 CalculatorHandler 类中实现。
清单 5 和 清单 6 协同工作,演示了 JavaScript 环境中初始化的和 Java 源文件中实现的代码交互。但是如何从 Activity 代码中初始化一些您想要在 WebView 中发生的动作呢?
现在应该更深入地来看 Java 代码了。
插入 JavaScript 代码
从将一个数学公式传递到 JavaScript 代码进行计算这样一个任务开始。JavaScript 最伟大(也最危险)的特性之一是 eval() 函数。eval() 函数允许字符串代码的运行时计算。在本例中,您从 EditText 控件接受一个字符串并传递到 JavaScript 环境进行计算。具体来说,我们调用 清单 6 中的 PerformSimpleCalculation() 函数。
清单 7 包含 AndroidJSON.java 中的代码,它负责处理按钮选择。
清单 7. 从 Java 调用 PerformSimpleCalculation() JavaScript 函数
btnSimple.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.i(tag,"onClick Simple"); // Perform action on click try { String formulaText = formula.getText().toString(); Log.i(tag,"Formula is [" + formulaText + "]" ); browser.loadUrl("javascript:PerformSimpleCalculation(" + formulaText + ");"); } catch (Exception e) { Log.e(tag,"Error ..." + e.getMessage()); } } });
不管此方法有多少行,这里唯一要关注的是 browser.loadurl() 行,它传递一个格式字符串:javascript:<code to execute>。
此 JavaScript 代码被注入到 WebView 的当前页面并执行。这样,Java 代码就可以执行 WebView 中定义的 JavaScript 代码了。
在 Simple 例子中,传递了一个字符串。但是,当需要处理更复杂的结构时该怎么办呢?这就是 JSON 可派上用场的地方。清单 8 展示了 PerformComplexCalculation() 函数的调用,该函数参见 清单 6。
清单 8. 通过传递一个 JSON 对象调用更复杂的函数
btnComplex.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.i(tag,"onClick Complex"); // Perform action on click try { String jsonText = ""; if (flipflop == 0) { jsonText = "{ \"operation\" : \"addarray\",\"arguments\" : [1,2,3,4,5,6,7,8,9,10]}"; flipflop = 1; } else { jsonText = "{ \"operation\" : \"multarray\",\"arguments\" : [1,2,3,4,5,6,7,8,9,10]}"; flipflop = 0; } Log.i(tag,"jsonText is [" + jsonText + "]" ); browser.loadUrl("javascript:PerformComplexCalculation(" + jsonText + ");"); } catch (Exception e) { Log.e(tag,"Error ..." + e.getMessage()); } } });
研究一下 清单 6 中的 JavaScript 函数 PerformComplexCalculation。注意,传递进来的参数不是字符串,而是您自己创建的一个对象。
* operation - 要处理的函数或过程的名称
* arguments - 这是一个整数数组
对象只包含两个属性,但是完全可以更复杂,以满足更高的需求。在本例中,PerformComplexCalculation() JavaScript 函数支持两种不同的操作:addarray 和 multarray。当这些操作在调用时完成其工作时,通过调用函数 window.calc.setAnswer,将结果传递回 Java 代码。这里,您看到了 Java 和 JavaScript 代码之间的双向数据流。
在本例中,您传递了一个 JSON 对象,但是得到的一条经验是,在处理从 Java 代码返回来的 Java 字符串时,它有助于将它们转换成 JavaScript 字符串。这可以像本例中一样通过将值传递给 String 函数来做到:eval(String(formula));。
JavaScript eval() 函数使用 JavaScript 字符串。无需转换的话,eval 函数基本上不做任何事情。
对于一个稍微复杂一点的例子,鼓励您好好看一下 Dynamic 按钮在 WebView 中被选中时的代码段。
要完成代码例子,来看一下将一个字符串数组从 JavaScript 环境传递到 Java 环境。
交换 JSON 对象
示例应用程序 (index.html) 中的 JavaScript 代码将本地函数调用记录到一个名为 cmdHistory 的页面级别数组中。每次调用函数时,您都将一个新条目添加到该数组中。例如,当 dynamicfunction() 被调用时,一个新的字符串被存储:cmdHistory[cmdHistory.length] = "PerformCompleCalculation-dynamic";。
关于此方法,没有什么特别的地方;它只是一个在页面级别收集使用数据的例子。也许该数据存储在 Android 应用程序的数据库中会有用。此数据如何回到 Java 代码呢?
要发送字符串对象数组,您调用 JSON.stringify 函数,将数组作为参数传递进来。根据需要,stringify 函数可以允许定制一个复杂对象的特定属性如何被格式化。关于这是如何完成的更多信息,可以参考 json.org 中的解释
- andjson.zip (58 KB)
- 下载次数: 31
发表评论
-
android listview
2012-07-13 17:37 927ListView与Button的共存问题解决, 解决在list ... -
演化理解 Android 异步加载图片
2011-11-09 09:55 902LinearLayout 布局,其下放了5个ImageView ... -
android常用颜色
2011-11-07 08:49 1279常用颜色值: 可以完美的颜色比对的网站: http://w ... -
dialog,activity 屏蔽Home键详解
2011-11-03 09:39 0http://www.iteye.com/topic/1116 ... -
android SlidingDrawer example
2011-11-03 09:35 0http://disanji.net/2010/12/16/a ... -
play flash swf file in android with webview
2011-11-03 09:34 0http://androidforums.com/applic ... -
AnimationDrawable 在Dialog中不能动画的原因(转)
2011-11-03 09:33 1302原来在dialog的onCreate onStart调用的时候 ... -
Free Android UI library & component roundup
2011-11-03 09:27 1146http://java.dzone.com/articles/ ... -
Android Fundamentals: Scheduling Recurring Tasks
2011-11-03 09:26 982http://mobile.tutsplus.com/tuto ... -
Android ListView pull up to refresh 改造(转)
2011-11-03 09:25 2097转自: http://dengyin2000.iteye.co ... -
Android中dp和px之间进行转换
2011-11-03 09:02 2260在xml布局文件中,我们既可以设置px,也可以设置dp(或者d ... -
view的setTag() 和 getTag()应用
2011-10-31 12:19 29933View中的setTag(Onbect)表示给View添加一个 ... -
使用getIdentifier()获取资源Id
2011-10-31 12:15 8457使用getIdentifier()获取资源Id int i ... -
ListView的长按菜单___源码分析
2011-10-24 09:28 2592ListView的长按菜单___源码分析 Android的l ... -
让你的Android程序兼容多种分辨率
2011-10-24 09:20 1024http://www.android123.com.cn/an ... -
andr菜单
2011-10-24 09:18 1208Android 菜单 菜单分为两种:系统菜单和上下文菜单。 ... -
Android 长按显示上下文菜单代码
2011-10-24 09:14 5938Android 长按显示上下文 ... -
Android Asynchronous Http Client
2011-10-19 10:27 2906转自: loopj.com/android-async-htt ... -
Android canvas.drawBitmap实现透明效果
2011-09-02 14:22 23434以下是针对,canvas.drawBitmap方法实施透明效 ... -
android资源别名
2011-08-30 14:24 2320详细请参考: http://developer.android ...
相关推荐
通过WebView,开发者可以在原生Android应用中嵌入HTML、CSS和JavaScript代码,从而构建混合式应用。 当需要在JavaScript和Android之间进行交互时,我们通常会用到`addJavascriptInterface()`方法。这个API允许我们...
在实际应用中,Android开发者通常会结合网络请求库如Retrofit或Volley来获取JSON数据,并使用Gson或Jackson等库进行自动映射到Java对象,以简化数据处理过程。同时,需要注意错误处理,确保在解析过程中能够正确处理...
Android提供了WebView组件,它允许在应用程序中嵌入一个浏览器内核,从而展示网页内容。为了实现H5与Android的交互,我们需要利用WebView提供的`addJavascriptInterface()`方法。这个方法允许我们将Java对象暴露给...
《Android应用程序开发宝典》是一本专为开发者设计的指南,涵盖了在飞凌嵌入式公司的OK6410、FL6410以及TE6410开发板上进行Android应用开发的全面知识。这本书深入浅出地讲解了如何在这些硬件平台上构建、调试和优化...
负载均衡采用Tomcat和Nginx代理服务器的混合模式,Tomcat负责JSON格式数据的解析,而Nginx则作为反向代理服务器,优化了网络请求的处理。 3. 前端交互与数据解析 前端与服务器之间的通信采用HTTP协议,通过JSONDUMP...
总的来说,理解Android与JavaScript的交互、JSON数据的传递以及EventBus的使用,对于提升Android应用的用户体验和代码质量至关重要。掌握这些技术,开发者可以更高效地构建功能丰富的混合式应用。
### Android中的JSON详解 #### JSON概述 JSON(JavaScript Object Notation),是一种轻量级的数据交换格式,因...通过这些类,开发者可以在Android应用中高效地解析和生成JSON数据,从而实现数据的灵活交换和处理。
Android 软件工程师是移动应用程序开发的核心人物,负责开发、测试和维护 Android 操作系统下的软件应用程序。为了成为一名合格的 Android 软件工程师,需要具备以下技术栈: 1. 数据存储方式:Android 提供了五种...
在本文中,我们将深入探讨如何使用Go语言以及特定的工具,如`gowebview`,来构建一个Android应用程序,该程序能够与您的Golang HTTP服务器进行交互。`gowebview`是一个开源项目,允许开发者使用Go语言创建原生的移动...
总的来说,Cordova(PhoneGap)Android混合开发中的值传递是一个复杂但灵活的过程,它需要理解JavaScript和Java的交互机制,以及如何利用Cordova提供的工具和API。通过熟练掌握这些技能,开发者可以构建出既具有Web...
标题中的“一个移动应用开发工具完全基于存储在JSON文件中的HTML创建App”指的是使用特定的开发工具,通过将HTML内容存储在JSON文件中,来构建跨平台的移动应用程序。这种开发方式结合了JSON的结构化数据特性和HTML...
在Android和JavaScript交互的过程中,开发者经常需要在两者之间进行数据传递和方法调用,以便实现更复杂的混合式应用开发。这种技术通常应用于Webview环境,其中Android原生代码与嵌入的网页内容进行互动。本篇文章...
在Android开发中,JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于应用程序与服务器之间的数据传输。理解如何在Android中解析JSON数据是至关重要的,这将帮助开发者有效地处理从网络获取的...
《Android应用开发揭秘》这本书是Android开发者们的重要参考资料,它深入浅出地揭示了Android应用程序开发的各个环节。从基础知识到高级技巧,从架构设计到性能优化,覆盖了Android开发的全貌。 首先,Android应用...
本系列的其他文章第 2 部分:使用 JSON 交付混合 Android 应用程序 本文介绍了 Android 应用程序上下文中的 XML 和 JSON 数据交换格式。 与 JSON 方法相比,XML 方法速度更快,内存限制更少 - 代价是额外的复杂性。 ...
在《Android应用开发大全6》中,我们深入探讨了Android平台上的应用程序开发,这是一个涵盖广泛且不断演进的领域。Android作为全球最流行的移动操作系统,为开发者提供了丰富的工具和技术来构建创新的应用。以下是对...
"基于Android的网上购物系统"是一个针对移动设备开发的电子商务应用程序,它允许用户在Android平台上进行在线购物。这样的系统通常包括商品浏览、搜索、添加到购物车、下单、支付以及用户反馈等一系列功能,为用户...
"hybrid_example:适用于 iOS 和 Android 的混合应用程序示例"是一个很好的学习资源,旨在帮助开发者理解如何构建既能运行在iOS又能在Android平台上,并且利用JavaScript技术的混合应用。 **什么是混合应用程序?** ...