refactor: 启动监控 Startup 命名统一为 Launch

- demo 页面与诊断类重命名:StartupLogin/StartupNetwork/StartupPrivacy → LaunchLogin/LaunchNetwork/LaunchPrivacy,StartupDiagnostics → LaunchDiagnostics(含 main_pages.json 注册与全部引用)
- 生产监控类重命名:StartupMonitor → LaunchMonitor,StartupElkBuilder → LaunchElkBuilder(含 EntryAbility/Index/LauncherPage/NetworkAnomalyPage 引用)
- 命名与 APP_LAUNCH 事件及 launch 模块对齐
- 接入方案文档同步页面名与类名,并修正 6 处过时内容:4 维度(is_first_install 入维度出候选)、分桶 4 维度、4.1 阶段时间已上传、§6 章节顺序(6.1 在 6.2 前)、§2 双通道链路
- demo 改名后 devecocli build 编译通过;真机运行回归待设备恢复补跑

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
clz
2026-08-06 14:24:31 +08:00
co-authored by Claude
parent 6fe0d2ec7a
commit 9e29282be3
14 changed files with 253 additions and 229 deletions
@@ -22,12 +22,12 @@ enum DrawReportState {
* 监听系统 APP_LAUNCH 事件,并确保一个进程生命周期内只提交一次
* reportDrawnCompleted。检测结果同时输出到 hilog 和模拟页面。
*
* 与 future_entry_demo 的 StartupMonitor.ets 对应:本文件为无依赖演示实现
* 与 future_entry_demo 的 LaunchMonitor.ets 对应:本文件为无依赖演示实现
* (仅 hilog + 页面展示,不做 ELK 上传),追溯字段已同步系统时间拆解字段
* 与 deviceInfo 环境字段;git_commit / is_first_install / build_mode 依赖
* biz_common 与 BuildProfile,演示工程不适用,故未同步。
*/
export class StartupDiagnostics {
export class LaunchDiagnostics {
private static readonly WATCHER_NAME: string = 'startupDiagnosticsWatcher';
private static readonly LOG_DOMAIN: number = 0xD002;
private static readonly MAX_EVENT_KEYS: number = 20;
@@ -64,17 +64,17 @@ export class StartupDiagnostics {
private static lastLaunchDetail: string = '尚未收到 APP_LAUNCH';
static initialize(context: common.UIAbilityContext): void {
if (StartupDiagnostics.watcherInitialized) {
if (LaunchDiagnostics.watcherInitialized) {
return;
}
// 首次安装标志:preferences 无启动记录视为首次,随后写入并同步落盘;异常时按非首次处理
try {
const pref: preferences.Preferences = preferences.getPreferencesSync(context, { name: 'startup_demo' });
StartupDiagnostics.isFirstInstall = !pref.getSync('has_launched', false);
LaunchDiagnostics.isFirstInstall = !pref.getSync('has_launched', false);
pref.putSync('has_launched', true);
pref.flushSync();
} catch (e) {
StartupDiagnostics.isFirstInstall = false;
LaunchDiagnostics.isFirstInstall = false;
}
const filter: hiAppEvent.AppEventFilter = {
@@ -82,27 +82,27 @@ export class StartupDiagnostics {
names: [hiAppEvent.event.APP_LAUNCH]
};
const watcher: hiAppEvent.Watcher = {
name: StartupDiagnostics.WATCHER_NAME,
name: LaunchDiagnostics.WATCHER_NAME,
appEventFilters: [filter],
onReceive: (domain: string, appEventGroups: Array<hiAppEvent.AppEventGroup>) => {
hilog.info(StartupDiagnostics.LOG_DOMAIN, 'StartupDiagnostics',
hilog.info(LaunchDiagnostics.LOG_DOMAIN, 'LaunchDiagnostics',
'APP_LAUNCH onReceive domain=%{public}s, groups=%{public}d', domain, appEventGroups.length);
StartupDiagnostics.processAppLaunchEvents(appEventGroups);
LaunchDiagnostics.processAppLaunchEvents(appEventGroups);
}
};
// 记录注册时间戳,用于区分本次启动事件与系统补投递的上次启动遗留事件
StartupDiagnostics.watcherRegisterTime = Date.now();
LaunchDiagnostics.watcherRegisterTime = Date.now();
try {
hiAppEvent.addWatcher(watcher);
StartupDiagnostics.watcherInitialized = true;
StartupDiagnostics.lastAction = 'APP_LAUNCH 监听已注册,等待首帧';
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.watcherInitialized = true;
LaunchDiagnostics.lastAction = 'APP_LAUNCH 监听已注册,等待首帧';
LaunchDiagnostics.notifyStatusChanged();
} catch (err) {
StartupDiagnostics.lastAction = `APP_LAUNCH 监听注册失败:${StartupDiagnostics.getErrorMessage(err)}`;
StartupDiagnostics.logError(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.lastAction = `APP_LAUNCH 监听注册失败:${LaunchDiagnostics.getErrorMessage(err)}`;
LaunchDiagnostics.logError(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
}
}
@@ -111,124 +111,124 @@ export class StartupDiagnostics {
abilityContext: common.UIAbilityContext,
pageName: string
): void {
if (StartupDiagnostics.drawReportState !== DrawReportState.IDLE) {
StartupDiagnostics.skippedReportCount++;
StartupDiagnostics.lastAction = `页面 ${pageName} 的重复首帧注册已跳过`;
StartupDiagnostics.logInfo(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
if (LaunchDiagnostics.drawReportState !== DrawReportState.IDLE) {
LaunchDiagnostics.skippedReportCount++;
LaunchDiagnostics.lastAction = `页面 ${pageName} 的重复首帧注册已跳过`;
LaunchDiagnostics.logInfo(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
return;
}
StartupDiagnostics.disposeFirstFrame(StartupDiagnostics.activeObserverOwner);
LaunchDiagnostics.disposeFirstFrame(LaunchDiagnostics.activeObserverOwner);
try {
const observer: inspector.ComponentObserver = createObserver();
const onDraw = (): void => {
observer.off('draw', onDraw);
if (StartupDiagnostics.activeObserverOwner === pageName) {
StartupDiagnostics.activeObserverOwner = '';
StartupDiagnostics.activeDisposer = undefined;
if (LaunchDiagnostics.activeObserverOwner === pageName) {
LaunchDiagnostics.activeObserverOwner = '';
LaunchDiagnostics.activeDisposer = undefined;
}
if (StartupDiagnostics.drawReportState !== DrawReportState.IDLE) {
StartupDiagnostics.skippedReportCount++;
StartupDiagnostics.lastAction = `页面 ${pageName} 的重复 draw 回调已跳过`;
StartupDiagnostics.notifyStatusChanged();
if (LaunchDiagnostics.drawReportState !== DrawReportState.IDLE) {
LaunchDiagnostics.skippedReportCount++;
LaunchDiagnostics.lastAction = `页面 ${pageName} 的重复 draw 回调已跳过`;
LaunchDiagnostics.notifyStatusChanged();
return;
}
StartupDiagnostics.drawCallbackCount++;
StartupDiagnostics.drawReportState = DrawReportState.SUBMITTED;
StartupDiagnostics.capturedEntryPage = pageName;
StartupDiagnostics.reportSubmitCount++;
StartupDiagnostics.lastAction = `已提交 ${pageName} 的 reportDrawnCompleted`;
StartupDiagnostics.logInfo(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.drawCallbackCount++;
LaunchDiagnostics.drawReportState = DrawReportState.SUBMITTED;
LaunchDiagnostics.capturedEntryPage = pageName;
LaunchDiagnostics.reportSubmitCount++;
LaunchDiagnostics.lastAction = `已提交 ${pageName} 的 reportDrawnCompleted`;
LaunchDiagnostics.logInfo(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
try {
abilityContext.reportDrawnCompleted((err) => {
if (err && err.code !== 0) {
StartupDiagnostics.drawReportState = DrawReportState.FAILED;
StartupDiagnostics.lastAction =
LaunchDiagnostics.drawReportState = DrawReportState.FAILED;
LaunchDiagnostics.lastAction =
`reportDrawnCompleted 失败:code=${err.code}, message=${err.message}`;
StartupDiagnostics.logError(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.logError(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
return;
}
StartupDiagnostics.drawReportState = DrawReportState.SUCCEEDED;
StartupDiagnostics.lastAction = `reportDrawnCompleted 成功:${pageName}`;
StartupDiagnostics.logInfo(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.drawReportState = DrawReportState.SUCCEEDED;
LaunchDiagnostics.lastAction = `reportDrawnCompleted 成功:${pageName}`;
LaunchDiagnostics.logInfo(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
});
} catch (err) {
// 同步异常表示异步任务未成功提交,恢复 IDLE 后允许其他页面重试。
StartupDiagnostics.drawReportState = DrawReportState.IDLE;
StartupDiagnostics.lastAction =
`reportDrawnCompleted 同步异常:${StartupDiagnostics.getErrorMessage(err)}`;
StartupDiagnostics.logError(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.drawReportState = DrawReportState.IDLE;
LaunchDiagnostics.lastAction =
`reportDrawnCompleted 同步异常:${LaunchDiagnostics.getErrorMessage(err)}`;
LaunchDiagnostics.logError(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
}
};
StartupDiagnostics.activeObserverOwner = pageName;
StartupDiagnostics.activeDisposer = (): void => {
LaunchDiagnostics.activeObserverOwner = pageName;
LaunchDiagnostics.activeDisposer = (): void => {
observer.off('draw', onDraw);
};
observer.on('draw', onDraw);
StartupDiagnostics.lastAction = `已监听 ${pageName} 根组件 draw`;
StartupDiagnostics.logInfo(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.lastAction = `已监听 ${pageName} 根组件 draw`;
LaunchDiagnostics.logInfo(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
} catch (err) {
StartupDiagnostics.lastAction = `创建 draw 监听失败:${StartupDiagnostics.getErrorMessage(err)}`;
StartupDiagnostics.logError(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.lastAction = `创建 draw 监听失败:${LaunchDiagnostics.getErrorMessage(err)}`;
LaunchDiagnostics.logError(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
}
}
static disposeFirstFrame(pageName: string): void {
if (pageName === '' || StartupDiagnostics.activeObserverOwner !== pageName) {
if (pageName === '' || LaunchDiagnostics.activeObserverOwner !== pageName) {
return;
}
const disposer: (() => void) | undefined = StartupDiagnostics.activeDisposer;
const disposer: (() => void) | undefined = LaunchDiagnostics.activeDisposer;
if (disposer !== undefined) {
disposer();
}
StartupDiagnostics.activeObserverOwner = '';
StartupDiagnostics.activeDisposer = undefined;
LaunchDiagnostics.activeObserverOwner = '';
LaunchDiagnostics.activeDisposer = undefined;
}
static setStatusUpdatedListener(owner: string, listener: () => void): void {
StartupDiagnostics.statusListenerOwner = owner;
StartupDiagnostics.statusUpdatedListener = listener;
LaunchDiagnostics.statusListenerOwner = owner;
LaunchDiagnostics.statusUpdatedListener = listener;
listener();
}
static clearStatusUpdatedListener(owner: string): void {
if (StartupDiagnostics.statusListenerOwner !== owner) {
if (LaunchDiagnostics.statusListenerOwner !== owner) {
return;
}
StartupDiagnostics.statusListenerOwner = '';
StartupDiagnostics.statusUpdatedListener = undefined;
LaunchDiagnostics.statusListenerOwner = '';
LaunchDiagnostics.statusUpdatedListener = undefined;
}
static getStatusText(): string {
return `状态:${StartupDiagnostics.getStateName()}\n` +
`捕获入口:${StartupDiagnostics.capturedEntryPage}\n` +
`draw 回调:${StartupDiagnostics.drawCallbackCount}\n` +
`系统提交:${StartupDiagnostics.reportSubmitCount}\n` +
`重复拦截:${StartupDiagnostics.skippedReportCount}\n` +
`APP_LAUNCH:${StartupDiagnostics.launchEventCount}\n` +
`事件去重:${StartupDiagnostics.duplicateEventCount}\n` +
`最近动作:${StartupDiagnostics.lastAction}\n` +
`事件详情:${StartupDiagnostics.lastLaunchDetail}`;
return `状态:${LaunchDiagnostics.getStateName()}\n` +
`捕获入口:${LaunchDiagnostics.capturedEntryPage}\n` +
`draw 回调:${LaunchDiagnostics.drawCallbackCount}\n` +
`系统提交:${LaunchDiagnostics.reportSubmitCount}\n` +
`重复拦截:${LaunchDiagnostics.skippedReportCount}\n` +
`APP_LAUNCH:${LaunchDiagnostics.launchEventCount}\n` +
`事件去重:${LaunchDiagnostics.duplicateEventCount}\n` +
`最近动作:${LaunchDiagnostics.lastAction}\n` +
`事件详情:${LaunchDiagnostics.lastLaunchDetail}`;
}
private static processAppLaunchEvents(appEventGroups: Array<hiAppEvent.AppEventGroup>): void {
for (let groupIndex: number = 0; groupIndex < appEventGroups.length; groupIndex++) {
const group: hiAppEvent.AppEventGroup = appEventGroups[groupIndex];
for (let infoIndex: number = 0; infoIndex < group.appEventInfos.length; infoIndex++) {
StartupDiagnostics.processAppLaunchEvent(group.appEventInfos[infoIndex]);
LaunchDiagnostics.processAppLaunchEvent(group.appEventInfos[infoIndex]);
}
}
}
@@ -238,13 +238,13 @@ export class StartupDiagnostics {
const params: Record<string, Object> = JSON.parse(paramsJson) as Record<string, Object>;
const startType: number = (params['start_type'] as number) ?? -1;
if (startType !== 0) {
StartupDiagnostics.logInfo(`跳过非冷启动事件:start_type=${startType}`);
LaunchDiagnostics.logInfo(`跳过非冷启动事件:start_type=${startType}`);
return;
}
const extendTime: number = (params['extend_time'] as number) ?? 0;
if (extendTime <= 0) {
StartupDiagnostics.logInfo('跳过尚未填充 extend_time 的 APP_LAUNCH');
LaunchDiagnostics.logInfo('跳过尚未填充 extend_time 的 APP_LAUNCH');
return;
}
@@ -252,17 +252,17 @@ export class StartupDiagnostics {
const iconInputTime: number = (params['icon_input_time'] as number) ?? 0;
const processName: string = (params['process_name'] as string) ?? '';
const eventKey: string = `${eventTime}|${iconInputTime}|${startType}|${processName}`;
if (StartupDiagnostics.processedEventKeys.indexOf(eventKey) !== -1) {
StartupDiagnostics.duplicateEventCount++;
StartupDiagnostics.lastAction = `重复 APP_LAUNCH 已拦截:${eventKey}`;
StartupDiagnostics.logInfo(StartupDiagnostics.lastAction);
StartupDiagnostics.notifyStatusChanged();
if (LaunchDiagnostics.processedEventKeys.indexOf(eventKey) !== -1) {
LaunchDiagnostics.duplicateEventCount++;
LaunchDiagnostics.lastAction = `重复 APP_LAUNCH 已拦截:${eventKey}`;
LaunchDiagnostics.logInfo(LaunchDiagnostics.lastAction);
LaunchDiagnostics.notifyStatusChanged();
return;
}
StartupDiagnostics.processedEventKeys.push(eventKey);
if (StartupDiagnostics.processedEventKeys.length > StartupDiagnostics.MAX_EVENT_KEYS) {
StartupDiagnostics.processedEventKeys.shift();
LaunchDiagnostics.processedEventKeys.push(eventKey);
if (LaunchDiagnostics.processedEventKeys.length > LaunchDiagnostics.MAX_EVENT_KEYS) {
LaunchDiagnostics.processedEventKeys.shift();
}
const bundleName: string = (params['bundle_name'] as string) ?? '';
@@ -276,23 +276,23 @@ export class StartupDiagnostics {
// 补投递事件(上次启动提交绘制但进程在事件送达前退出)的 capturedEntryPage 是当前进程的快照,
// 不能错误归因到本次启动的页面,因此补报事件的入口标记为未知。
const isBackfill: boolean = StartupDiagnostics.isBackfillEvent(iconInputTime);
const isBackfill: boolean = LaunchDiagnostics.isBackfillEvent(iconInputTime);
StartupDiagnostics.launchEventCount++;
StartupDiagnostics.lastLaunchDetail =
LaunchDiagnostics.launchEventCount++;
LaunchDiagnostics.lastLaunchDetail =
`extend_time=${extendTime}ms, icon_input_time=${iconInputTime}, ` +
`start_type=${startType}, process_name=${processName}\n` +
`bundle_name=${bundleName}, bundle_version=${bundleVersion}\n` +
`response_latency=${responseLatency}ms, animation_finish_time=${animationFinishTime}ms\n` +
`startability_processstart_dur=${startabilityProcessStartDur}ms, ` +
`appattach_to_appforeground_dur=${appattachToAppForegroundDur}ms\n` +
`device_type=${StartupDiagnostics.getDeviceType()}, ` +
`system_version=${StartupDiagnostics.getSystemVersion()}\n` +
`is_first_install=${StartupDiagnostics.isFirstInstall}\n` +
`device_type=${LaunchDiagnostics.getDeviceType()}, ` +
`system_version=${LaunchDiagnostics.getSystemVersion()}\n` +
`is_first_install=${LaunchDiagnostics.isFirstInstall}\n` +
`补报事件=${isBackfill ? '是(entry_page 不归因,按 unknown 处理)' : '否'}`;
StartupDiagnostics.lastAction = '已捕获有效冷启动 APP_LAUNCH';
StartupDiagnostics.logInfo(StartupDiagnostics.lastLaunchDetail);
StartupDiagnostics.notifyStatusChanged();
LaunchDiagnostics.lastAction = '已捕获有效冷启动 APP_LAUNCH';
LaunchDiagnostics.logInfo(LaunchDiagnostics.lastLaunchDetail);
LaunchDiagnostics.notifyStatusChanged();
}
/**
@@ -301,7 +301,7 @@ export class StartupDiagnostics {
* 补报事件的 icon_input_time 早于注册时间超过容差(至少 5 秒的送达延迟)。
*/
private static isBackfillEvent(iconInputTime: number): boolean {
return iconInputTime < StartupDiagnostics.watcherRegisterTime - StartupDiagnostics.BACKFILL_TOLERANCE_MS;
return iconInputTime < LaunchDiagnostics.watcherRegisterTime - LaunchDiagnostics.BACKFILL_TOLERANCE_MS;
}
private static getDeviceType(): string {
@@ -313,7 +313,7 @@ export class StartupDiagnostics {
}
private static getStateName(): string {
switch (StartupDiagnostics.drawReportState) {
switch (LaunchDiagnostics.drawReportState) {
case DrawReportState.IDLE:
return 'IDLE';
case DrawReportState.SUBMITTED:
@@ -328,7 +328,7 @@ export class StartupDiagnostics {
}
private static notifyStatusChanged(): void {
const listener: (() => void) | undefined = StartupDiagnostics.statusUpdatedListener;
const listener: (() => void) | undefined = LaunchDiagnostics.statusUpdatedListener;
if (listener !== undefined) {
listener();
}
@@ -339,10 +339,10 @@ export class StartupDiagnostics {
}
private static logInfo(message: string): void {
hilog.info(StartupDiagnostics.LOG_DOMAIN, 'StartupDiagnostics', '%{public}s', message);
hilog.info(LaunchDiagnostics.LOG_DOMAIN, 'LaunchDiagnostics', '%{public}s', message);
}
private static logError(message: string): void {
hilog.error(StartupDiagnostics.LOG_DOMAIN, 'StartupDiagnostics', '%{public}s', message);
hilog.error(LaunchDiagnostics.LOG_DOMAIN, 'LaunchDiagnostics', '%{public}s', message);
}
}
@@ -17,7 +17,7 @@ import { AbilityConstant, common, ConfigurationConstant, UIAbility, Want } from
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { CrashDiagnostics } from '../diagnostics/CrashDiagnostics';
import { StartupDiagnostics } from '../diagnostics/StartupDiagnostics';
import { LaunchDiagnostics } from '../diagnostics/LaunchDiagnostics';
import { AuthSession } from '../session/AuthSession';
const DOMAIN = 0x0000;
@@ -26,7 +26,7 @@ export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
try {
CrashDiagnostics.initialize(this.context as common.UIAbilityContext);
StartupDiagnostics.initialize(this.context as common.UIAbilityContext);
LaunchDiagnostics.initialize(this.context as common.UIAbilityContext);
AuthSession.initialize(this.context as common.UIAbilityContext);
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} catch (err) {
@@ -46,7 +46,7 @@ export default class EntryAbility extends UIAbility {
// Main window is created, set main page for this ability
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
const initialPage: string = AuthSession.isLoggedIn() ? 'pages/Index' : 'pages/StartupLogin';
const initialPage: string = AuthSession.isLoggedIn() ? 'pages/Index' : 'pages/LaunchLogin';
windowStage.loadContent(initialPage, (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
@@ -5,7 +5,7 @@
import { common } from '@kit.AbilityKit';
import { CrashDiagnostics } from '../diagnostics/CrashDiagnostics';
import { StartupDiagnostics } from '../diagnostics/StartupDiagnostics';
import { LaunchDiagnostics } from '../diagnostics/LaunchDiagnostics';
import { AuthSession } from '../session/AuthSession';
import crashNative from 'libentry.so';
@@ -20,7 +20,7 @@ struct Index {
@State recordCount: number = 0;
aboutToAppear(): void {
StartupDiagnostics.reportFirstFrameOnDraw(
LaunchDiagnostics.reportFirstFrameOnDraw(
() => this.getUIContext().getUIInspector().createComponentObserver('STARTUP_HOME_ROOT'),
this.getUIContext().getHostContext() as common.UIAbilityContext,
PAGE_NAME
@@ -34,7 +34,7 @@ struct Index {
}
aboutToDisappear(): void {
StartupDiagnostics.disposeFirstFrame(PAGE_NAME);
LaunchDiagnostics.disposeFirstFrame(PAGE_NAME);
CrashDiagnostics.clearRecordsUpdatedListener();
}
@@ -44,7 +44,7 @@ struct Index {
return;
}
try {
this.getUIContext().getRouter().replaceUrl({ url: 'pages/StartupLogin' }).catch((err: Error) => {
this.getUIContext().getRouter().replaceUrl({ url: 'pages/LaunchLogin' }).catch((err: Error) => {
this.statusText = `退出登录后跳转失败:${err.message}`;
});
} catch (err) {
@@ -4,23 +4,23 @@
*/
import { common } from '@kit.AbilityKit';
import { StartupDiagnostics } from '../diagnostics/StartupDiagnostics';
import { LaunchDiagnostics } from '../diagnostics/LaunchDiagnostics';
import { AuthSession } from '../session/AuthSession';
const PAGE_NAME: string = 'StartupLogin';
const PAGE_NAME: string = 'LaunchLogin';
@Entry
@Component
struct StartupLogin {
struct LaunchLogin {
@State account: string = 'demo@example.com';
@State password: string = '123456';
@State startupStatus: string = StartupDiagnostics.getStatusText();
@State startupStatus: string = LaunchDiagnostics.getStatusText();
aboutToAppear(): void {
StartupDiagnostics.setStatusUpdatedListener(PAGE_NAME, () => {
this.startupStatus = StartupDiagnostics.getStatusText();
LaunchDiagnostics.setStatusUpdatedListener(PAGE_NAME, () => {
this.startupStatus = LaunchDiagnostics.getStatusText();
});
StartupDiagnostics.reportFirstFrameOnDraw(
LaunchDiagnostics.reportFirstFrameOnDraw(
() => this.getUIContext().getUIInspector().createComponentObserver('STARTUP_LOGIN_ROOT'),
this.getUIContext().getHostContext() as common.UIAbilityContext,
PAGE_NAME
@@ -28,41 +28,41 @@ struct StartupLogin {
}
aboutToDisappear(): void {
StartupDiagnostics.disposeFirstFrame(PAGE_NAME);
StartupDiagnostics.clearStatusUpdatedListener(PAGE_NAME);
LaunchDiagnostics.disposeFirstFrame(PAGE_NAME);
LaunchDiagnostics.clearStatusUpdatedListener(PAGE_NAME);
}
private openNetworkScenario(): void {
this.navigateTo('pages/StartupNetwork');
this.navigateTo('pages/LaunchNetwork');
}
private openPrivacyScenario(): void {
this.navigateTo('pages/StartupPrivacy');
this.navigateTo('pages/LaunchPrivacy');
}
private completeLogin(): void {
if (!AuthSession.setLoggedIn(true)) {
this.startupStatus = `保存登录状态失败,请重试。\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `保存登录状态失败,请重试。\n${LaunchDiagnostics.getStatusText()}`;
return;
}
try {
this.getUIContext().getRouter().replaceUrl({ url: 'pages/Index' }).catch((err: Error) => {
this.startupStatus = `进入首页失败:${err.message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `进入首页失败:${err.message}\n${LaunchDiagnostics.getStatusText()}`;
});
} catch (err) {
const message: string = err instanceof Error ? err.message : JSON.stringify(err);
this.startupStatus = `进入首页同步异常:${message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `进入首页同步异常:${message}\n${LaunchDiagnostics.getStatusText()}`;
}
}
private navigateTo(url: string): void {
try {
this.getUIContext().getRouter().pushUrl({ url: url }).catch((err: Error) => {
this.startupStatus = `页面跳转失败:${err.message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `页面跳转失败:${err.message}\n${LaunchDiagnostics.getStatusText()}`;
});
} catch (err) {
const message: string = err instanceof Error ? err.message : JSON.stringify(err);
this.startupStatus = `页面跳转同步异常:${message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `页面跳转同步异常:${message}\n${LaunchDiagnostics.getStatusText()}`;
}
}
@@ -4,20 +4,20 @@
*/
import { common } from '@kit.AbilityKit';
import { StartupDiagnostics } from '../diagnostics/StartupDiagnostics';
import { LaunchDiagnostics } from '../diagnostics/LaunchDiagnostics';
const PAGE_NAME: string = 'StartupNetwork';
const PAGE_NAME: string = 'LaunchNetwork';
@Entry
@Component
struct StartupNetwork {
@State startupStatus: string = StartupDiagnostics.getStatusText();
struct LaunchNetwork {
@State startupStatus: string = LaunchDiagnostics.getStatusText();
aboutToAppear(): void {
StartupDiagnostics.setStatusUpdatedListener(PAGE_NAME, () => {
this.startupStatus = StartupDiagnostics.getStatusText();
LaunchDiagnostics.setStatusUpdatedListener(PAGE_NAME, () => {
this.startupStatus = LaunchDiagnostics.getStatusText();
});
StartupDiagnostics.reportFirstFrameOnDraw(
LaunchDiagnostics.reportFirstFrameOnDraw(
() => this.getUIContext().getUIInspector().createComponentObserver('STARTUP_NETWORK_ROOT'),
this.getUIContext().getHostContext() as common.UIAbilityContext,
PAGE_NAME
@@ -25,18 +25,18 @@ struct StartupNetwork {
}
aboutToDisappear(): void {
StartupDiagnostics.disposeFirstFrame(PAGE_NAME);
StartupDiagnostics.clearStatusUpdatedListener(PAGE_NAME);
LaunchDiagnostics.disposeFirstFrame(PAGE_NAME);
LaunchDiagnostics.clearStatusUpdatedListener(PAGE_NAME);
}
private retryNetwork(): void {
try {
this.getUIContext().getRouter().replaceUrl({ url: 'pages/StartupLogin' }).catch((err: Error) => {
this.startupStatus = `页面跳转失败:${err.message}\n${StartupDiagnostics.getStatusText()}`;
this.getUIContext().getRouter().replaceUrl({ url: 'pages/LaunchLogin' }).catch((err: Error) => {
this.startupStatus = `页面跳转失败:${err.message}\n${LaunchDiagnostics.getStatusText()}`;
});
} catch (err) {
const message: string = err instanceof Error ? err.message : JSON.stringify(err);
this.startupStatus = `页面跳转同步异常:${message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `页面跳转同步异常:${message}\n${LaunchDiagnostics.getStatusText()}`;
}
}
@@ -4,20 +4,20 @@
*/
import { common } from '@kit.AbilityKit';
import { StartupDiagnostics } from '../diagnostics/StartupDiagnostics';
import { LaunchDiagnostics } from '../diagnostics/LaunchDiagnostics';
const PAGE_NAME: string = 'StartupPrivacy';
const PAGE_NAME: string = 'LaunchPrivacy';
@Entry
@Component
struct StartupPrivacy {
@State startupStatus: string = StartupDiagnostics.getStatusText();
struct LaunchPrivacy {
@State startupStatus: string = LaunchDiagnostics.getStatusText();
aboutToAppear(): void {
StartupDiagnostics.setStatusUpdatedListener(PAGE_NAME, () => {
this.startupStatus = StartupDiagnostics.getStatusText();
LaunchDiagnostics.setStatusUpdatedListener(PAGE_NAME, () => {
this.startupStatus = LaunchDiagnostics.getStatusText();
});
StartupDiagnostics.reportFirstFrameOnDraw(
LaunchDiagnostics.reportFirstFrameOnDraw(
() => this.getUIContext().getUIInspector().createComponentObserver('STARTUP_PRIVACY_ROOT'),
this.getUIContext().getHostContext() as common.UIAbilityContext,
PAGE_NAME
@@ -25,26 +25,26 @@ struct StartupPrivacy {
}
aboutToDisappear(): void {
StartupDiagnostics.disposeFirstFrame(PAGE_NAME);
StartupDiagnostics.clearStatusUpdatedListener(PAGE_NAME);
LaunchDiagnostics.disposeFirstFrame(PAGE_NAME);
LaunchDiagnostics.clearStatusUpdatedListener(PAGE_NAME);
}
private acceptPrivacy(): void {
this.navigateTo('pages/StartupLogin');
this.navigateTo('pages/LaunchLogin');
}
private showNetworkError(): void {
this.navigateTo('pages/StartupNetwork');
this.navigateTo('pages/LaunchNetwork');
}
private navigateTo(url: string): void {
try {
this.getUIContext().getRouter().replaceUrl({ url: url }).catch((err: Error) => {
this.startupStatus = `页面跳转失败:${err.message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `页面跳转失败:${err.message}\n${LaunchDiagnostics.getStatusText()}`;
});
} catch (err) {
const message: string = err instanceof Error ? err.message : JSON.stringify(err);
this.startupStatus = `页面跳转同步异常:${message}\n${StartupDiagnostics.getStatusText()}`;
this.startupStatus = `页面跳转同步异常:${message}\n${LaunchDiagnostics.getStatusText()}`;
}
}
@@ -1,8 +1,8 @@
{
"src": [
"pages/StartupLogin",
"pages/StartupNetwork",
"pages/StartupPrivacy",
"pages/LaunchLogin",
"pages/LaunchNetwork",
"pages/LaunchPrivacy",
"pages/Index",
"pages/CrashHistory"
]