1. 引擎或模块问题:
遇到应用层无法解决的问题,如果能确定需要引擎和模块支持的,不要自己想办法绕过去,要第一时间在开发者社区提交问题,或找 APICloud 项目经理提出。
- 在开发者社区中,会有版主和 APICloud 技术支持对您的问题进行验证和解答。
- 定制平台项目问题提出后 2 天之内没有解决的,可以直接找 APICloud 项目总监投诉。
2. 开发工具:
推荐使用 Sublime Text+APICloud 插件,调试工具使用自定义 Loader,真机同步使用 WiFi 真机同步,日志输出使用 WiFi 日志输出。
3. 前端框架:
尽量不要使用 jQuery、AngularJS、BootStrap 等重型的框架,摆脱对 $ 的依赖,培养自己动手的习惯,但是可以根据功能需求在特定页面中使用功能独立的 Mobile First 框架
- 默认样式设置、DOM 操作和字符串处理推荐使用 APICloud 前端框架 (api.js 和 api.css)
- 移动端 UI 框架推荐使用 AUI
4. 屏幕适配:
要正确设置 viewport,建议使用 720*1280 尺寸的 UI 图,优先考虑绝对计量类的单位 px,应先在 UI 效果图中(如 720x1280 尺寸图)量出元素的宽或高对应的 px 值,再除以屏幕倍率(如分辨率为 720x1280 设备的屏幕倍率通常为 2) 来得到书写样式时的确切数值。
- APICloud 项目验收时会根据设计提供的 UI 图尺寸(如 720x1280),在对应屏幕分辨率的手机设备 (如 720x1280)中安装运行,将运行后的页面与 UI 效果图一一进行对比。
- H5 界面的实现要与 UI 设计完全一致,精细到 0.5px。
- openFrame/FrameGroup 等时,应使用 auto 结合 margin 布局,以动态适应变化无常的 android 设备屏幕。
- 推荐文档:屏幕适配原理及实现
5. UI 布局:
- 要求使用 APICloud 五大组件(Widget、Layout、Window、Frame、UIModules)进行 APP 的 UI 架构设计。
- SPA 的模式不适合 APP 开发,DIV+JS 的窗口切换影响用户体验。APICloud 的 UI 结构设计可以从整体上解决 H5 在 Interaction、Animation 和 Render 方面的性能问题。
- 推荐文档:培训讲义:APICloud 界面布局和 APP 架构设计
6. 窗口切换:
避免出现任何卡顿、闪屏、白屏等情况;动画效果流畅,不能出现丢帧的情况。
要理解并控制窗口好切与界面渲染之间的关系,要适时更新 UI,如果 Window 或 Frame 中所加载的静态页面内容过多,建议等动画执行完毕再进行页面的加载和渲染。无论是 Android 还是 iOS 系统,在进行窗口切换的时候,如果窗体本身正在进行渲染(Window 或 Frame 所加载的网页没有渲染完毕),则会影响切换动画运行的流畅性,出现卡顿或丢帧的情况。
建议在打开 Window 或 Frame 的时候,如果所加载的静态网页不能过大,内容不要太多,不能快速的渲染完毕。为了不影响窗体切换动画的执行,可以在切换动画执行完毕后再进行动态数据的加载和界面的刷新。
7. 窗口切换动画:
- 如果没有特别要求尽量使用平台默认的动画效果,即 api.openWin 时不指定动画类型,使用默认值。
- 无论是在 Android 还是 iOS 上,APICloud 引擎会从整体上保证默认的窗口动画类型是性能最好的。
- 三星、小米等大屏 Android6.0 及以上手机,可以尝试在云编译的时候选择使用 Android 引擎渲染优化版本
- 如果窗体所加载的静态网页内容比较多 (如:初始的 Dom 树很大或图片很多),在 Android 平台上 openWindow 的时候可以尝试使用 movein 或 fade 的动画类型
8. 窗口关闭处理:
开发过程中根据需要处理 Android 的 keyback 事件和 iOS 的回滑手势。
Android 上要在 Window 中才能监听到 keyback 事件,Frame 中无法监听到 keyback 事件;在 iOS7 以上的系统上可以在 openWin 的时候通过设置 slidBackEnabled 参数来实现是否支持回滑手势关闭窗口的功能。
在后台关闭页面时,应注意在关闭方法中添加 animation:{type:"none"},来防止切换动画的出现影响用户体验;
9. 窗体背景图片:
- 避免使用 H5 来实现 body 级别的背景图片,可以使用 Window 或 Frame 的 bgColor 参数以原生的方式来高效实现
- 不建议通过给 body 元素指定 background 的方式来实现 body 级别的背景图片,特别是高清的大背景图片用 H5 方式实现会严重影响渲染性能。
10. 导航切换:
切换底部导航或顶部分类菜单的时候,要求切换体验平滑,切换过程不能出现白屏、闪屏等现象
建议使用 FrameGroup 来实现 Frame 的切换,要按需合理配置预加载的 Frame 数量,每个 Frame 要有明显的刷新机制,不能每次切换都进行刷新和重绘。
如果使用模块来实现底部导航栏推荐使用 NVTabBar 模块。
11. 列表滚动:
滚动效果要平滑流畅,不能使用 iscroll 等 JS 的方式来实现滚动
建议使用 Window Frame 的 UI 结构,以 Native 的方式来实现列表页面的滚动。
在 iOS 上要支持点击状态栏能自动回到顶部的效果,可以通过在 openWin 或 openFrame 的时候配置 scrollToTop 参数来实现;此效果在 FrameGroup 中使用的时候要注意确保只有当前显示的 Frame 的 scrollToTop 属性为 true,其它 Frame 的 scrollToTop 属性为 false。
12. 界面之间参数传递:
可以使用 pageParam 来实现,但要避免使用过大的 pageParam。界面切换的时候如果 pageParam 过大,则 JSON 解析就会比较耗时,影响界面切换的执行和动画运行体验。
不要使用使用 URL ? 的形式进行参数的传递,此方式在 Android 上存在兼容问题。
13. 交互响应:
点击事件必须处理 click 事件的 300ms 延迟问题,优化点击响应速度,建议通过为可点击的元素增加 tapmode 属性来优化点击速度。
引擎对具有 tapmode 属性的元素点击事件的优化处理会在 apiready 事件触发之前,根据当前的 dom 树自动进行优化。在 apiready 之后加载的数据使用要显式的调用 api.parseTapmode 方法来进行主动的 tapmode 处理,例如在上拉加载更多数据后,要调用一下 api.parseTapmode 方法.
要按 UE 设计确定可点击区域的大小,可以适当扩大点击区域来保障点击反应的灵敏。
api.parseTapmode 调用会有性能成本,不需要的情况下不要随便调用。
要按照需求明确所有按钮点击时的交互效果,为 tapmode 属性设置正确的样式值,对于没有交互效果的点击实现,可以不为 tapmode 属性指定任何样式,但是为了优化点击速度,必须要给元素增加 tapmode 属性。
14. 下拉刷新效果:
建议不要使用 APICloud 默认的下拉刷新效果(灰色箭头),要使用模块来实现 UE/UI 所设计的下拉刷新效果。
如果 UE/UI 所设计的下拉刷新效果,使用目前 APICloud 平台模块无法实现,要第一时间跟项目经理提出,由 APICloud 进行模块封装来实现。
15. 网络通信方式:
必须使用 api.ajax,并且设置合适的超时时间,并进行超时和请求失败的异常情况。
JQuery 的 ajax 在开启全包加密的时候会有问题,不建议使用。
16. 网络请求状态处理:
APP 要判断当前的网络状态,请求过程要按 UI 设计有明显的状态提示;网络超时或网络请求失败的时候要进行相关处理并有错误提示。
api 对象和 dialogBox 模块下面封装了常用的提示对话框方法。
17. 数据缓存:
要对 GET 请求进行数据的缓存处理,在用户没用网络的情况下,仍然能够看到 APP 的静态界面布局以及上次已经缓存的服务器端数据。
可以在 api.ajax 方法中设置 cache 参数为 true 来开启缓存;也可以使用 api.writeFile 和 api.readFile 方法,在获取数据后自己实现简单的数据缓存,或使用 fs 和 db 模块来缓存数据。
18. 图片缓存:
必须手动进行图片的缓存处理,需要调用 api.imageCache 方法实现。
Webview 默认的缓存机制存在缺陷,在跨窗口时表现不好,并且存在对所缓存图片的尺寸限制等问题,所有 APICloud 应用的图片缓存不能依赖 Webview 默认的缓存机制,必须手动实现。
19. 图片处理:
要减少由图片造成的内存占用,减少图片缩放等耗性能的操作,服务器端要根据产品设计提供合适尺寸的大图、小图、缩略图等
APICloud 应用所占用的内存大小由所加载的网页大小决定,通常图片过多过大会造成整个应用的内存占用过大,另外在浏览器中进行图片的缩放处理成本也很高。
列表中的头像等缩略图,宽高应控制在 250-300px 之间,小于这个范围大屏手机容易失真,大于这个范围消耗更多内存和性能。
20. 状态栏效果:
Android 和 iOS 上都要求实现沉浸式状态栏效果的适配
可以通过在 config.xml 中开启沉浸式效果] 配置项,然后在 Window 或 Frame 的 apiready 事件后,调用 $api.fixStatusBar() 方法来实现。如果由于各种原因造成 apiready 执行太晚,当 Header 高度变化时会产生页面跳动的现象,也可以根据需求自己来实现,在合适的时机(如 onload 事件中)判断平台类型后,手动调整 Header 的高度,Android 的状态栏高度是 25px,iOS 是 20px。
要根据当前界面的背景颜色,通过调用 api.setStatusBarStyle 方法来设置当前状态栏的风格或背景色。
21. 键盘处理:
在打开带有输入框的 Window 或 Frame 的是,默认要自动让输入框自动获得焦点。
在 config.xml 中有关于键盘显示方式,弹出方式和第三方键盘使用的各种配置,要根据需要正确配置。
由于在 Android 上 input 元素的 focus 事件存在兼容性问题,要完成输入框自动获取焦点的功能,建议使用扩展模块 UIInput 模块。
在打开 Window 的时候,如果自动弹出键盘,弹出键盘的行为影响切换动画执行的流畅性,出现卡顿或丢帧的情况。建议可以对键盘弹出的行为设置适当的延迟,例如在 apiready 中设置延迟 200ms 后再让 UIInut 元素获得焦点。
可以在同一个界面中(如登陆界面)创建多个 UIInput 模块的实例,来实现多个输入框。
输入框位于设备屏幕下半部份的应用场景,config.xml 中的的键盘弹出模式参数 softInputMode 务必设置为 resize 模式,或者使用 UIInput 相关模块。
为了让应用看起来更接近原生,尽量配置 config.xml 中的 softInputBarEnabled 参数来隐藏 iOS 键盘上面的工具条。也可以在 openWin 或 openFrame 的时候通过 softInputBarEnabled 参数来单独指定。
22. 配置外部字体:
可以根据项目的需要引入外部字体,但是要控制外部字体文件的大小,字体文件不宜过大。
Android 上默认有 3 种字体:sans, serif, monospace,在开发人员不指定的情况下,默认为 sans,这 3 种字体在开发过程中都是通过字体名进行引用,系统会自动对应到内置字体文件。但是,对于外部的字体文件,Android 上无法实现通过引擎配置后成为内置的字体文件,只能通过 @font-face 的方式在每个页面中重复加载,每一个要使用外部字体的 Window 或 Frame 都要引入一遍,如果字体体积过大会占用大量内存,并且影响页面的加载速度。
iOS 可以在 config.xml 文件中进行外部字体文件的配置,配置完成后就可以像系统内置字体一样在页面中指定了,无需在每个 Window 或 Frame 中通过 @font-face 的方式引入。
23. JavaScript 模版:
建议使用 doT 模版等轻量级的模版。
要优先选择使用 Mobile First 的模版,体量小,生成的文本效率高。
doT 模版文档
24. 支付业务:
支付宝,微信等密钥必须存放在服务器端,不应暴露在 APP 代码中。
支付订单金额应由服务器产生,服务器一定要对支付宝、微信服务器回调的支付结果做最终校验。
alipay 模块要调用 payOrder 方法来进行支付,自己处理订单信息以及签名过程;不要使用 config 接口和 pay 接口把订单信息以及签名过程交予模块内部处理(官方提供此种支付方式只是为了方便开发者调试)。
25. 使用同步接口:
对于文件、数据库、偏好设置等操作推荐使用同步接口 (方法名增加 Sync 后缀) 来简化代码的实现,解决异步 callback 层次过深的问题。
- fs 对象的同步方法
- db 对象的同步方法
- 偏好设置操作的同步方法
对于异步 callback 嵌套的问题,也可以通过调用 api.sendEvent 方法来解耦,通过事件机制来实现。
26. 网页代码组织:
尽量将同一个界面的 HTML、CSS 和 JS 代码写在一个 html 文件中,提高页面加载速度;公用的 CSS、JS 尽量少和小,不要在 html 页面中随意加载无用的 CSS 或 JS 文件;尽量减少页面中的 link 或 script 标签的使用。在浏览器中,外部文件的引入和加载过程是同步操作,影响整个页面的执行效率。
27. 应用代码组成:
- 要遵循 APICloud Widget 包结构,结构清晰规范。
- 推荐文档:APICloud Widget 包结构
28. 文件命名规范:
要有统一规范,如首页 Windowhome 文件命名为 home.html,首页 Frame 文件命名为 home_frame.html,所有文件名 (网页和资源文件) 避免使用中文命名、也不要包含大写字母。原生系统内部资源文件管理不支持中文名和大写字母,使用中文或大写的资源文件在真实设备运行中会出现各种问题。
例如在自定义 Loader 中运行没有问题,但云编译的包就有问题,出现页面无法加载或资源找不到等问题,通常就是使用了中文或大写的文件命名。因为官方 Loader 或自定义 Loader 的 Widget 是存放在 SDCard 中,而云编译后的安装包 Widget 是存在应用的沙箱中,沙箱中是要采用的原生系统的内部资源文件管理机制。
29. 安全机制:
要从代码、数据存储、网络通信等方面保证 APP 的内容和数据的安全。
开发过程中每次云编译的无论测试包还是正式包都建议选择全包加密,因为在 APICloud 定制平台上,客户可以全程监控项目的实施过程,可以查看代码提交纪录,但是没有获取代码的权限;客户可以查看云编译纪录,如果编译的安装包没有使用全包加密则客户可能通过解压安装包轻松获取 APP 的 H5 源码,从而影响后续项目款的按时支付。
- config.xml 中的 access 配置项可以配置在哪些类型的页面里面可以访问 APICloud 的扩展 API 方法,可访问域的设置以及越狱限制等。
- config.xml 中的 checkSslTrusted 配置项配置是否检查 https 证书是受信任的。
- config.xml 中的 appCertificateVerify 配置项配置是否校验应用证书。若配置为 true,应用被重签名后将无法再使用。
- 对重要参数变量进行必要的加密处理,对重要的常量数据应放入 key.xml 中,使用 api.loadSecureValue 方法进行数据读取;
30. 安装包大小:
云编译生成的安装包的大小由 4 部分内容组成:引擎、模块、网页文件和资源文件。引擎的大小是固定的(Android 约为 400K,iOS 约为 1.2M),应该控制减少模块、网页文件和资源文件的大小,删除无用的模块和文件。
编译正式版本的时候,要检查一下控制台选定的模块是否都在实际代码中使用到了。一些开发者在开发过程中会不断引入一些 “预计使用” 或 "测试使用" 的模块,但是在最终的代码中没有使用,这部分模块要云编译的时候去掉,无用的模块不仅仅会增大安装包的体积,还有可能引起于其它模块的冲突或编译选项,造成编译失败。
在 config.xml 文件中配置的模块,在控制台无法删除,因为 config 中 feature 配置项的 forceBind 属性默认 true,是强制绑定的,可以通过在配置 forceBind 属性来修过。
在编译正式版本的时候,要删除 Widget 包中的 icon 和 launch 目录下的图片以减小安装包体积。