HarmonyOS鸿蒙Next中在woker中调用单例对象,到调用对象函数的地方就报not initialized
HarmonyOS鸿蒙Next中在woker中调用单例对象,到调用对象函数的地方就报not initialized
我封装了一个logger类,用于将程序运行的日志写入到本地,最后可以供下载。在实现worker的ets中调用这个logger类实例的时候,就会报not initialized。但是在UI相关的ets文件中调用这个类,就不会报错,可以正常写入。这是啥原因?如何规避?
模拟器版本:
报错截图:
关键类SdpLogger实现(末尾定义了一个此类的实例导出用于其他ets调用):
/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { hilog } from '@kit.PerformanceAnalysisKit';
import { common } from '@kit.AbilityKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { getLogFile } from '../workers/localFile';
const LOG_TAG = 'AppLogger';
export const LOG_ERROR:number = 0;
export const LOG_WARN:number = 1;
export const LOG_INFO:number = 2;
export const LOG_DEBUG:number = 3;
enum LogLevel {
ERROR = 0, //错误
WARN = 1, //警告
INFO = 2, //一般
DEBUG = 3 //调试
}
export class SdpLogger {
private domain: number;
private prefix: string;
private format: string = '%{public}s';
private logFile:string = '';
private logLevel:number = 0;
setLogLevel(value:number){
this.logLevel = value;
}
setLogFile(path:string){
this.logFile = path;
}
constructor(prefix: string) {
const currentDate = new Date();
const year = currentDate.getFullYear();
const month = ("0" + (currentDate.getMonth() + 1)).slice(-2);
const day = ("0" + currentDate.getDate()).slice(-2);
// 组合完整的日期时间字符串
let logFileName:string = `${year}${month}${day}`;
this.prefix = prefix;
this.domain = 0x0001;
this.logLevel = LOG_ERROR;
let context = getContext() as common.UIAbilityContext;
this.logFile = context.filesDir + '/sdp_log.txt';
console.log('logfile init is '+this.logFile);
const files = fs.listFileSync(context.filesDir);
console.log('logfile init list :'+files)
}
// 写入日志到文件
private writeToFile(msg: string): void {
try {
console.log('写入文件内容:here 1');
const file:fs.File = fs.openSync(this.logFile,
fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE
);
console.log('写入文件内容:here 2');
const timestamp = new Date().toString();
const logLine = `${timestamp} [${LOG_TAG}] ${msg}\n`;
// const encoder = new util.TextEncoder(); // 创建UTF-8编码器
// const uint8Array = encoder.encode(logLine); // 字符串 → Uint8Array
// 1. 获取文件状态(含大小)
console.log('写入文件内容:here 3');
const stats = fs.statSync(this.logFile);
console.log('写入文件内容:here 4');
const offset = stats.size; // 文件当前字节长度
// 2. 以追加模式打开文件
fs.writeSync(file.fd, logLine, { offset });
console.log('写入文件内容:here 5');
console.log('写入文件内容:'+logLine);
//fs.writeSync(file.fd, uint8Array.buffer); // 写入文件
fs.closeSync(file);
console.log('写入文件内容:here 6');
} catch (err) {
hilog.error(0x0000, LOG_TAG, `${this.logFile},写日志失败: ${JSON.stringify(err)}`);
}
}
debug(...args: string[]) {
hilog.debug(this.domain, this.prefix, this.format, args);
this.writeToFile(`INFO: ${args}`);
}
info(...args: string[]) {
hilog.info(this.domain, this.prefix, this.format, args);
this.writeToFile(`INFO: ${args}`);
}
warn(...args: string[]) {
hilog.warn(this.domain, this.prefix, this.format, args);
this.writeToFile(`INFO: ${args}`);
}
error(...args: string[]) {
hilog.error(this.domain, this.prefix, this.format, args);
this.writeToFile(`INFO: ${args}`);
}
fatal(...args: string[]) {
hilog.fatal(this.domain, this.prefix, this.format, args);
this.writeToFile(`INFO: ${args}`);
}
log(level:number,...args: string[]) {
let TAG = '';
if(level>=this.logLevel)
{
switch (level){
case LOG_DEBUG:
TAG = 'DEBUG';
hilog.debug(this.domain, this.prefix, this.format, args);
break;
case LOG_INFO:
TAG = 'INFO';
hilog.info(this.domain, this.prefix, this.format, args);
break;
case LOG_WARN:
TAG = 'WARN';
hilog.warn(this.domain, this.prefix, this.format, args);
break;
case LOG_ERROR:
TAG = 'ERROR';
hilog.error(this.domain, this.prefix, this.format, args);
break;
}
this.writeToFile(`${TAG}: ${args}`);
}
}
isLoggable(level: number) {
hilog.isLoggable(this.domain, this.prefix, level);
}
}
export const sdp_logger = new SdpLogger('[sdp_client]');
worker的接收消息处引用sdp_logger这个单例并报错
更多关于HarmonyOS鸿蒙Next中在woker中调用单例对象,到调用对象函数的地方就报not initialized的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,Worker线程调用单例对象报"not initialized"错误,是因为单例未在主线程初始化。鸿蒙的单例对象需要在主线程先完成初始化才能在Worker中使用。解决方法是在应用启动时(如Ability的onCreate)先调用该单例的getInstance()方法进行初始化。Worker线程中调用时需确保单例已初始化完成。注意单例的线程安全问题,必要时加同步锁。
更多关于HarmonyOS鸿蒙Next中在woker中调用单例对象,到调用对象函数的地方就报not initialized的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html