模块开发指南_Android_Eclipse
参考视频://docs.apicloud.com/APICloud/videos-and-codes
第一章 SDK简介
Eclipse版模块包是APICloud自定义结构的标准zip包。APICloud模块扩展SDK是基于DeepEngine(以下称引擎)开放的一套标准化扩展机制,用于支持开发者灵活扩展任意原生功能到APICloud平台。 平台现有的模块如果无法满足您的需求,可通过该SDK进行模块扩展,在多个项目中复用,为应用开发节省大量的重复性工作,您也可以将开发完成的模块提交到模块商店,分享给开发者使用。 本SDK提供给有一定Android原生开发基础的开发者,通过简单的接口实现和标准的Android开发流程,快速扩展模块,轻松接入APICloud平台。
一个完整的SDK包命名类似:ModulesDevProject_Android.zip。解压后是一个标准的Eclipse工程目录,如图所示:
备注:其中readme.txt是与版本描述相关的说明文件。
第二章 阅读对象
本文档面向所有使用该SDK的Android开发人员、测试人员、合作伙伴以及对此感兴趣的其他用户。阅读该文档要求用户熟悉Android应用开发,熟悉Android Eclipse开发工具的基本使用,并且对Html、CSS、Javascript有一定了解,熟悉Java和Javascript中JSON格式数据的操作。
第三章 SDK功能说明
本SDK是开发者快速了解使用APICloud跨平台移动应用开发引擎,并熟练掌握模块开发技巧及了解APICloud移动应用云平台的桥梁。
i.框架设计
引擎通过实现对操作系统底层能力的封装和扩展,基于H5引擎开放API给JS调用的形式,实现了HTML+CSS+JS开发语言和Object-C/Java/C/C++等原生开发语言之间的桥接,极大的丰富和增强了标准H5的能力。令前端开发者通过JS即可调用移动设备的底层功能,如:电话、短信、定位、多媒体、跨域http请求等,并能将如百度地图、支付宝等第三方厂商的SDK很容易的集成至App中来。
本SDK开放桥接机制,方便具有一定Android基础的开发者灵活扩展模块,丰富JS的能力,提升App的用户体验。引擎框架桥接层设计如图:
ii. 主要功能
本SDK主要提供以下功能和接口:
映射一个Java类的函数和常量(统称为模块module)至Javascript对象的函数和常量,包括:
-被映射Java类的函数、属性及常量书写规范
-module.json文件的声明
往当前屏幕window中插入/移除一个或者多个自定义View,包括:
-直接插入View至window
-获取一个Activity的View并插入window
在module中启动另一个Activity或App并获取回调,包括:
-直接启动Activity
-启动Activity并获取返回值
启动widget、向window注入Javascript,包括:
-在module中调用引擎的widget管理能力启动widget
-向APP的某活动window注入并执行一段Javascript
扩展模块项目资源ID的管理,包括:
-引擎及所有模块中均不允许出现R文件的引用。
-R文件对应的资源文件ID由引擎负责管理
扩展模块生命周期的管理:
-动态初始化和分配内存
-生命周期事件回调等
第四章 开发前准备
i. 开发环境:
PC:Windows XP/Win7/8/10 Mac OS;
Eclipse3.7及以上;
ADT21及以上;
Android SDK 21(5.0)及以上;
JDK1.6或者1.7。尽量不要使用1.8,存在各种潜在问题;
其中Android环境推荐使用Google整合版的Eclipse:SDK ADT Bundle;
下载地址:http://developer.android.com/sdk/index.html#download(Google已废弃,可通过其他途径下载,或者使用Studio)
ii. 开发帮助参考:
详细的SDK帮助文档://docs.apicloud.com/superwebview/Android/
Android在线API文档:https://developer.android.google.cn/reference/packages.html
Javascript规范及入门:http://www.w3school.com.cn
JSON数据在线Viewer:http://www.bejson.com/go.html?u=http://www.bejson.com/jsonview2/
第五章 使用SDK进行模块开发
i. 导入SDK工程到Eclipse
解压ModulesDevProject_Android.zip至任意目录
在Eclipse中导入该SDK,操作步骤:Eclipse ->File ->Import ->General ->Existing Project into Workspace ->Browser ->选择1中解压的目录 ->Finish即可
导入后的工程结构如图:
ii. 开始开发模块
- 新建用于绑定映射至JS对象的Java类。在项目中新建Java类(以下以APIModuleDemo.java类为例,映射的JS对象为moduleDemo),继承自引擎Jar包中的APIModule或者UZModule类,并重写相关函数。如下图:
- 定义开放API。若希望将Java类中的某个函数开放给JS调用,只需将该函数声明以“jsmethod_”开头,并且声明该函数为public,同时接收且仅接收一个类型为UZModuleContext的参数即可。
函数声明格式:
public void jsmethod_func(final UZModuleContextmoduleContext){
}
引擎会在初始化的时候,根据Java函数是否包含“jsmethod_”的前缀,而将该函数映射至JS对象。例如声明“jsmethod_showAlert”,引擎会将“jsmethod_showAlert”函数映射至模块对应JS对象的“showAlert”函数,开发者在Html页面中即可使用moduleDemo.showAlert(argument)的方式直接调用至Java的jsmethod_showAlert函数,并进行相关操作。
如下图中的定义:
实现了向JS对象映射:
- showAlert:弹出一个对话框,接收定义为“msg”字段的参数作为对话内容;
- startActivity:启动一个Activity;
- startActivityForResult:启动一个Activity并要求返回值;
- vibrate:调用设备震动器震动;
这四个函数,在JS中使用:
- moduleDemo.showAlert(argument);
- moduleDemo.startActivity(argument);
- moduleDemo.startActivityForResult(argument);
- moduleDemo.vibrate(argument);
即可调用到对应的Java函数中;
注意:
以“jsmethod_”前缀声明的Java函数,引擎默认在UI线程中操作该函数,因此请勿在该函数内部做耗时的操作,避免引起UI阻塞,抛出异常,耗时操作可另起线程进行。
- 获取来自JS传入的参数。
扩展机制规范要求前端JS开发者必须使用JSON格式数据作为JS与原生(Java)之间交换数据的传参。引擎将对JS传入的参数进行处理并封装,通过包装成UZModuleContext类传递给声明“jsmethod_”前缀的函数。
UZModuleContext类是JS与原生(Java)之间通信的运行时上下文封装,既是JS提交给Java数据的载体,同时也是Java回调JS的执行者。UZModuleContext内部封装了JSON数据操作的所有方法,如optInt、optString等,UZModuleContext同时还封装了success、error等回调JS的方法。
例如Html页面代码为:
uzmoduledemo.showAlert({msg:"Hello APICloud!"});
在Java中可通过类似如下方式获取JS传入的msg值:
public void jsmethod_showAlert(final UZModuleContext moduleContext){
String showMsg = moduleContext.optString("msg");
}
- 将操作结果回调至JS。
JS与原生之间遵循异步访问机制,Java做完相关操作后,应该将操作结果回调给JS,或者通知JS本次操作成功与否,错误提示等。该回调过程由UZModuleContext下的success、error等函数完成。如下代码实现了对“showAlert”结果的回调,将用户点击对话框按钮的操作通知JS:
JSONObject ret = new JSONObject();
try {
ret.put("buttonIndex", 1);
} catch (JSONException e) {
e.printStackTrace();
}
moduleContext.success(ret, true);
- 在模块声明文件module.json中声明该类。开发者务必在module.json文件中声明被映射Java类的class路径,以及其所开放给JS的模块名称,引擎将根据该配置检索相应的Java类,并在适当时候将其初始化。
module.json文件固定存放于assets/uzmap目录中。 存储格式为JSON格式,包含modules、name、class等字段。声明标准如下:
{
"modules":[
{
"name":"moduleDemo",
"class":"com.apicloud.moduleDemo.APIModuleDemo"
},
{
"name":"xxxDemo",
"class":"com.xxx.Objxxx"
},
{
"name":"xxxDemo1",
"class":"com.xxx.Objxxx1"
}
]
}
字段解释:
- name:定义该扩展模块开放给JS的模块对象名,类似于标准JS中的window、document、Math等对象。
class:定义该扩展模块对应绑定至JS的Java类及其路径。
导出模块包
模块开发调试完毕后,需要将你的代码及资源按照APICloud模块结构要求导出成模块包(zip格式),通过APICloud网站控制台提交。
- 模块包结构预览
导出模块包操作关键步骤:
(1)导出所有代码与你模块相关的代码文件到jar包里。操作步骤:File -> Export ->JAR file ->勾选需要导出代码及目录,next即可。如果有需要导出的assets资源,在可在该步骤勾选,将其导出到jar包里;
(2)从工程res目录中分离出所有与你的模块相关的资源文件,且不改变其所在目录;
(3)从工程AndroidManifest文件中分离出你的模块所定义的任何activity、service、provider、permission等;
(4)将1、2、3步骤得到的文件按照模块包结构说明复制到moduleDemo目录下对应目录中;
(5)将moduleDemo目录压缩成zip格式包;
第六章 模块开发Demo简介
本SDK默认展示5个扩展模块demo。其中:
- moduleDemo演示一个扩展模块的完整过程。扩展一个名为moduleDemo的JS对象,并将该对象映射至Java类(APIModuleDemo)的过程,同时展示如何在html页面中通过JS调用该模块。
APIModuleDemo类下每个API都有详细注释及使用实例,请开发者仔细阅读,同时请关注assets/widget目录下html页面的书写内容。
详细注释图:
- moduleRefresh演示如何进行下拉刷新模块的开发。
- moduleScrollPicture演示如何进行UI类模块的开发,并实现了类似UIScrollPicture模块的轮播图效果功能。
- eventdemo演示如何使用ApplicationDelegate类监听整个应用的生命周期,并进行相关的操作。
- syncInterface样式如何进行同步API的扩展。
第七章 SDK主要API简介
本章节提供引擎所有与模块扩展相关的API说明。
i.类
本SDK开放数个关键类:APIModule(UZModule)、ApplicationDelegate、UZModuleContext、ModuleResult、RefreshHeader、UZResourcesIDFinder,以及若干工具类API及常量,如:UZUtility、APICloudHttpClient等。
类 | 描述 |
---|---|
APIModule(UZModule) | 所有扩展模块的基类,Java类通过继承该类并声明相应函数,实现Java类绑定映射至JS对象,并开放API |
UZModuleContext | JS函数映射至Java函数时,传递参数的载体,同时也是Java回调结果至JS的执行者。包含操作标准JSON的方法 |
ApplicationDelegate | 应用生命周期的回调代理类。可通过定义类继承实现该类,并在module.json中配置声明,实现对应用生命周期的监听。 |
ModuleResult | 模块同步接口,返回结果时的包装类。模块开放同步接口时,在使用”sync”标识某接口为同步接口的同时,该接口需将数据结果通过ModuleResult包装后返回 |
RefreshHeader | 下拉刷新头模块的父类,所有下拉刷新头类的模块,必须继承该类,并实现相关函数,同时必须在module.json中配置该类。 |
UZUtility | 基础工具类,定义了许多实用函数,如获取外部存储路径,相对/绝对路径转换等 |
APICloudHttpClient | api.ajax(http、https)的原生API,管理所有请求,支持get、post、delete、下载等常见操作,支持同步请求,取消等。可直接调用,实现远程数据的获取,图片异步下载,资源缓存等 |
ii.重要API
APIModule(UZModule)对象:
API | 描述 |
---|---|
runOnUiThread | 在UI线程中执行操作 |
startActivityForResult | 启动一个Activity并要求返回值。所有使用APICloud SDK扩展的模块,在需要startActivityForResult时,都必须调用该接口,而不能直接调Activity的startActivityForResult |
getFeatureValue | 获取当前应用widget的config文件中feature字段的值 |
insertViewToCurWindow | 插入一个自定义的View到当前window中 |
removeViewFromCurWindow | 从当前window移除某个自定义View |
makeRealPath | 将一个任意协议的路径,如标准的content://,res://,以及APICloud扩展的widget://,fs://,cache://转换为系统可识别的真实路径 |
inImmerseState | 当前app是否处于”沉浸式”效果下。 |
onActivityResult | 通过startActivityForResult时,回调结果可重写此接口获取 |
getContext | 获取运行时上下文 |
getSecureValue | 获取当前应用widget的key.xml文件中字段的值。 |
onClean | 引擎主动回调函数,当window或者frame关闭以及当前页面发生url变化时,引擎会主动回调该接口,开发者应该在此接口中清理当前模块占用的资源,如网络资源,内存资源等 |
UZModuleContext对象:
API | 描述 |
---|---|
success | 模块正常回调结果给JS |
error | 当模块内部发生异常时,通过此接口回调结果给JS |
interrupt | 不处理回调。建议模块开发中,不想处理回调JS时,调用一下该函数 |
opt* | 各种操作JSON数据的方法 |
第八章 模块包结构说明
一个模块包根目录以该模块的JS对象名命名(以下以moduleDemo为例),二级子目录通常包含如下图目录结构:
目录解释:
(1)、res_xxxx目录:xxx为您的扩展模块名。该目录与Android项目中的资源文件目录res目录及结构保持一致,包含drawable、layout、values等子目录。在模块包中,该目录下只需对应存放你的模块中用到的资源文件即可。详情见资源规范细则。结构类似下图:
(2)、source目录:存放你的代码导出的jar包,依赖的jar包,以及相关源代码的目录,如jar、java、c、cpp等文件。如下图:
(3)、target目录:用于存放本模块用到的so动态库文件。如下图:
特别说明:armeabi架构的so直接放到target根目录(必须的),其他架构的so连同目录放置在target下(如果没有提供armeabi的so,则将armeabi-v7a的放置在target根目录)。target目录最终的结构如下:
target/libxxx.so
target/armeabi-v7a/libxxx.so
target/x86/libxxx.so
target/arm64-v8a/libxxx.so
...
(4)、AndroidManifest.xml文件:存放你的模块中用到的权限,定义的activity,service,provider等清单组件。详情见资源规范细则。结构如下图所示:
(5)、module.json文件,其内容必须类似如下:
{
"name":"moduleDemo",
"class":"com.apicloud.moduleDemo.APIModuleDemo"
}
如果一个模块包中包含多个模块入口,则配置类似如下:
{
"name":"moduleDemo",
"class":"com.apicloud.moduleDemo.APIModuleDemo"
},
{
"name":"moduleDemo1",
"class":"com.demo.ModuleDemo1"
},
{
"name":"moduleDemo2",
"class":"com.demo.ModuleDemo2"
}
第九章 其他
i.模块资源文件命名规范
建议开发者在开发过程中对资源文件的命名遵循如下规则:mo + 模块名 + 功能或UI类型 + 资源类型。
例如(以moduleDemo模块为例):
命名一个布局资源文件:
mo_moduledemo_demo_activity_layout.xml
命名一个图片资源文件:
mo_moduledemo_backbtn_press_bg.png
mo_moduledemo_layout_bg.png
命名一个字符资源文件:
mo_moduledemo_init_msg
mo_moduledemo_error_msg
ii.引擎固有资源说明
SDK工程目录下的任意原有资源文件,开发者不应随意改动,需保持其原状,否则SDK可能在启动过程中报找不到引擎资源的警告而强制退出,或者破坏模块开发环境与云编译环境的一致性。
ii.其他说明
在开始模块开发之前,建议阅读《开发模块设计规范》。
第十章 模块审核规范
开发者开发的模块务必遵守《模块审核规范-Android》。