Appearance
启动阶段 js 日志追踪
小程序在启动阶段若加载失败,常需要回溯 JS 侧 console 输出以便排查。JsView 提供 consoleRecord 能力:在引擎侧缓存 console.debug/log/info/warn/error,再在合适的时机读上传服务器,或直接写入文件后将文件进行上传(上传操作需要应用层自行完成)。
本章描述用到的对象说明:
JsView.java: Java 接口文档
MainPageProxy / MiniAppObserver / MiniAppLifecycleCallback: SDK java 文档
1. consoleRecord 相关 API
以下接口均位于 JsView 上。
enableConsoleRecord
开启 console 日志录制。开启后,JS 侧 console.debug / console.log / console.info / console.warn / console.error 的输出会被缓存。
java
/**
* @param capacity 缓存条数上限;
* 小于 0 表示不限制条数;
* 大于等于 0 表示最多保留该数量(超出时丢弃最早的记录)
*/
public void enableConsoleRecord(int capacity);disableConsoleRecord
关闭 console 日志录制,并清空已缓存的记录。
java
public void disableConsoleRecord();getRecordedConsole
获取当前已录制的 console 日志文本。
java
/**
* @return 录制内容字符串;每条记录一行,格式为 "HH:MM:SS.mmm Priority message"
*/
public String getRecordedConsole();saveRecordedConsole
将已录制的 console 日志保存到指定文件。
java
/**
* @param fileName 目标文件路径;文件不存在时会创建,已存在则覆盖写入
*/
public void saveRecordedConsole(String fileName);2. 通过 MainPageProxy 在启动阶段使用
推荐分工:
| 时机 | 接口位置 | 动作 |
|---|---|---|
| 小程序创建(引擎中设置url前) | MiniAppLifecycleCallback.onAppCreate | enableConsoleRecord 开启录制 |
| 加载成功 | MiniAppObserver.onMiniAppLoadSuccess | 仅 disableConsoleRecord 关闭录制 |
| 加载失败 | MiniAppObserver.onMiniAppLoadFail | getRecordedConsole / saveRecordedConsole 收集日志,再 disableConsoleRecord |
说明:
- 必须在 Lifecycle 的
onAppCreate中开启录制。该回调发生在 URL 设置之前,能尽量覆盖启动阶段的 JS console 输出;若开得太晚,早期日志会丢失。 - 成功路径不收集日志:启动正常时无需保留 recorder 缓存,在
onMiniAppLoadSuccess中直接关闭即可,避免无意义的内存占用。 - 失败路径再收集:仅在
onMiniAppLoadFail中读取或落盘,再关闭 recorder。 - 建议激活全局错误堆栈打印:为便于收集 JS 错误时的行号等信息,建议在 JS 代码中通过
window.JsvCoreApi.addGlobalJsExceptionAck注册全局异常监听,并在回调里将name/message/stack打印到console,这样错误堆栈会进入 consoleRecord 缓存,后续getRecordedConsole/saveRecordedConsole即可一并拿到。接口说明见 addGlobalJsExceptionAck。
js
window.JsvCoreApi.addGlobalJsExceptionAck((name, message, stack) => {
console.log("JsException:", name, message, stack);
});样例
java
mMainPageProxy = new MainPageProxy(this);
// 1) 失败时收集日志;成功时只关闭 recorder
mMainPageProxy.setMiniAppObserver(new MiniAppObserver() {
@Override
public void onMiniAppStartLoad(MiniApp miniApp) {
}
@Override
public void onMiniAppLoadProgress(MiniApp miniApp, int progress) {
}
@Override
public void onMiniAppLoadSuccess(MiniApp miniApp) {
// 启动成功:关闭录制并清空缓存,不做日志收集
miniApp.getJsView().disableConsoleRecord();
}
@Override
public void onMiniAppLoadFail(MiniApp miniApp, int errorCode) {
// 启动失败:先取出(或落盘)已录制的 console,再关闭录制
String consoleInfo = miniApp.getJsView().getRecordedConsole();
Log.d(TAG, "load fail, console length="
+ (consoleInfo == null ? 0 : consoleInfo.length()));
// 可选:落盘便于后续上传或本地分析
String consoleSavePath = getFilesDir().getAbsolutePath() + "/recorded_console.log";
miniApp.getJsView().saveRecordedConsole(consoleSavePath);
miniApp.getJsView().disableConsoleRecord();
}
@Override
public void onMiniAppVisibleReady(MiniApp miniApp) {
}
});
mMainPageProxy.onCreate(savedInstanceState /*, rootView */);
// 2) 在 Lifecycle.onAppCreate 中尽早开启录制
mMainPageProxy.getJSViewParent().registerMiniAppLifecycleCallback(
new MiniAppLifecycleCallback() {
@Override
public void onAppCreate(MiniApp miniApp) {
// 第一时间拿到尚未设置 url 的 JsView 句柄
miniApp.getJsViewAsync(jsView -> {
// -1:不限制缓存条数;也可按需传入正数上限
jsView.enableConsoleRecord(-1);
});
}
@Override
public void onAppStart(MiniApp miniApp) {
}
// ... 其他生命周期回调按需实现
});相关接口文档:
- MainPageProxy.setMiniAppObserver
- JSViewParent.registerMiniAppLifecycleCallback
- MiniAppObserver
- MiniAppLifecycleCallback
3. 启动完成后继续收集 console
第 2 节推荐在 onMiniAppLoadSuccess 中调用 disableConsoleRecord()。若业务需要在运行过程中出错时也能上传近期 console 做排查,启动成功后可以不关闭录制,继续缓存日志。
注意:
- 不要长期使用
enableConsoleRecord(-1)这种无限长度模式,内存会随运行时间持续增长。 - 建议在合适时机(例如启动成功时)再次调用
enableConsoleRecord,将缓存条数控制在约 150 左右;超出上限时会丢弃最早的记录,只保留最近一段日志。
样例
java
@Override
public void onMiniAppLoadSuccess(MiniApp miniApp) {
// 不 disable:改为限制容量,继续收集运行期 console
// 便于后续异常时 getRecordedConsole / saveRecordedConsole 后上传排查
miniApp.getJsView().enableConsoleRecord(150);
}
// 运行过程中发生错误时(示例:异常回调 / 业务自定义错误处理)
void onRuntimeError(MiniApp miniApp) {
String consoleInfo = miniApp.getJsView().getRecordedConsole();
// 或落盘后由应用层自行上传
// miniApp.getJsView().saveRecordedConsole(path);
}