1.官方的指南
模块SDK下载
http://docs.apicloud.com/Download/download
Android版模块开发指南
http://docs.apicloud.com/Dev-Guide/module-dev-guide-for-android
iOS 版模块开发指南
http://docs.apicloud.com/Dev-Guide/module-dev-guide-for-ios
2.Android版模块开发
开发样例是Eclipse+ADT,而不是Android Studio.
首先把完整项目即如下目录项目导入Eclipse当中,
ModulesDevProject_Android-->APICloudSDK
它是一个原生的测试程序,可以运行下看几个demo模块的效果.
2.1模块定义
APICloud引擎要求Native模块扩展开发者必须在module.json文件中声明被映射Java类的class路径,以及其所映射的JS对象名称。APICloud引擎根据该文件寻找相应Java类,并在适当时候将其初始化。
module.json文件固定存放于assets下的uzmap目录中,不得更改。存储格式为JSON格式,包含modules、name、class等字段。
插件定义样例文件,这个一看明白.
{
modules:[
{
name:'eas',
class:'com.apicloud.eventdemo.EasDelegate'
},
{
name:'moduleDemo',
class:'com.apicloud.moduleDemo.APIModuleDemo'
},
{
name:'scrollPicture',
class:'com.apicloud.moduleScrollPicture.ModuleScrollPicture'
},
{
name:'cusHeader',
class:'com.apicloud.moduleRefresh.CusRefreshHeader'
},
{
name:'syncModule',
class:'com.apicloud.syncInterface.SyncModule'
}
]
}
javascript中调用模块方法,,首先用api.require("")初始化,然后直接调用模块方法即可
function vibrate(){
uzmoduledemo = api.require('moduleDemo');
uzmoduledemo.vibrate(true);
}
2.2 模码源码
每个module必须由UZModule 基类
新建用于绑定映射至JS对象的类。在项目中新建Java类(以下以UZModuleDemo类为例,映射的JS对象为moduleDemo),继承自引擎Jar包中的APIModule或者UZModule类,并重写相关函数。
定义并声明将被映射至JS类的Java函数。 若想将Java类中的某个函数映射至JS对象供JS调用,需要将该函数声明以“jsmethod_”开头,并且声明该函数为public,同时接收且仅能接受一个参数:UZModuleContext。
函数声明格式:
public void jsmethod_showAlert(final UZModuleContextmoduleContext){}
APICloud引擎会在初始化的时候,根据Java函数是否包含“jsmethod_”的前缀,而将该函数映射至JS对象。例如声明“jsmethod_showAlert”,APICloud引擎会将“jsmethod_showAlert”函数映射至JS的“showAlert”函数,开发者在Html页面中即可使用moduleDemo.showAlert(argument)的方式直接调用至Java的jsmethod_showAlert函数,并进行相关操作。
APICloud引擎要求前端JS开发者必须使用JSON格式数据作为JS与Native之间交换数据的传参。APICloud引擎会对JS传入的参数进行解析并封装,通过包装成UZModuleContext类传递给声明“jsmethod_”前缀的函数。
UZModuleContext类是JS与Native之间通信的运行时上下文封装,既是JS提交给Native数据的载体,同时也是Native回调JS的执行者。UZModuleContext内部封装了JSON格式数据操作的所有方法,如optInt、optString等,UZModuleContext同时还封装了success、error等回调JS的方法。
模块接收参数
模块返回结果
调用 UZModuleContext.success(); 方法返回
调用 UZModuleContext.error(); 方法返回错误
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == Activity.RESULT_OK && requestCode == ACTIVITY_READ_TAG){
String result = data.getStringExtra("nfcId");
if(null != result && null != mJsCallback){
try {
JSONObject ret = new JSONObject();
ret.put("nfcId", result);
mJsCallback.success(ret, true);
mJsCallback = null;
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
网页中使用回调
nfcTag = api.require('nfcTag');
var resultCallback = function(ret, err){
// alert(JSON.stringify(ret));
document.getElementById("nfcData").value = ret.nfcId;
}
nfcTag.read(param, resultCallback);
可以参考
3 Android 模块导出
- 目录结构参考 模块测试项目下的 readme的 moduledemo.zip 的结构来建
- 导出所有代码与你模块相关的代码文件到jar包里。操作步骤:File -> Export ->JAR file ->选择你的代码,一路next即可。
- 从工程res目录中分离出所有与你的模块相关的资源文件,且不改变其所在目录; 3. 从工程AndroidManifest文件中分离出你的模块所定义的任何Activity、Service以及权限等;
注意要把 Activtiy外层的 Application 去掉.反编译发现它会合并到主 AndroidManifest.xml 当中,有这个反而错了.
- 将1、2、3步骤得到的文件对应拷入moduleDemo目录下对应目录中;
- 将moduleDemo目录压缩成zip格式包;
3.1 导出几个坑
1 . 注意导出jar放在 source目录下,我第一次写成sources,编译也不会报错,只是源码不会最终打包,模块也无法使用,最后反编译+检查官方给的例子才发现这个问题.
- 第二个module.json不要直接用测试项目里那个,而是去掉外围定义,直接描述模块
{
name:'moduleDemo',
class:'com.apicloud.moduleDemo'
}
如果直接套用这个,也不会报错,只是模块也用不了.在文档就一下带,很容易入坑.
- 导出资源时要手工把与模块相关资源一一导出,简单复制过来会容易与系统库有冲突.
- assets 里的内容需要在 export jar 一同打包
4.模块使用和调试
在控制台模块上传模块,并且加入项目,即可
但是这样程序是用不了,需要自定义loader把这个模块打包成一个新的apk才能调试.