Napi回调ArkTS,Native侧日志通过监听回调到JS侧

Native侧日志通过监听回调到JS侧

HarmonyOS
2024-05-23 21:54:51
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
ssscan

通过JS侧向Native侧注册日志监听接口,在Native侧任一业务中调用log接口将日志通过回调上报JS侧

export default interface OnLogsListener { 
​ 
onLogs(level:LogLevel,message:string) 
​ 
)

具体实现

1、ArkTS侧实现OnLogsListener 接口,实现onLogs方法

export class LogsListener implements OnLogsListener { 
 public constructor() { 
​ 
} 
​ 
 onLogs(level: LogLevel, message: string): void { 
   switch (level) { 
     case LogLevel.DEBUG: 
       hilog.debug(0x0000, 'debug', 'debug message is %{public}s', message); 
       break; 
     case LogLevel.INFO: 
       hilog.info(0x0000, 'info', 'info message is %{public}s', message); 
       break; 
     case LogLevel.ERROR: 
       hilog.error(0x0000, 'error', 'error message is %{public}s', message); 
       break; 
     default: 
       hilog.info(0x0000, 'info', 'info message is %{public}s', message); 
  } 
} 
} 
​ 
​ 
enum LogLevel { 
 DEBUG, 
 INFO, 
 ERROR 
} 
​ 
export default interface OnLogsListener { 
 onLogs(level: number, message: string): void; 
​ 
}

2、在native侧增加注册方法,注册该接口,注意这里使用napi_create_reference创建引用,napi_ref由自己管理对象的生命周期,不受NativeScope影响。

napi_ref logListenerRef = nullptr; 
napi_ref onLogsFuncRef = nullptr; 
​ 
static napi_value RegisterLogListener(napi_env env, napi_callback_info info) { 
   size_t argc = 1; 
​ 
   napi_status status; 
​ 
   napi_value globalThisAdapter = nullptr; 
   status = napi_get_cb_info(env, info, &argc, &globalThisAdapter, nullptr, nullptr); 
​ 
​ 
   napi_value getLogListenerFunc = nullptr; 
   status = napi_get_named_property(env, globalThisAdapter, "geLogsListener", &getLogListenerFunc); 
​ 
   napi_value logListener = nullptr; 
   status = napi_call_function(env, globalThisAdapter, getLogListenerFunc, 0, nullptr, &logListener); 
​ 
   napi_value onLogsFunc = nullptr; 
   status = napi_get_named_property(env, logListener, "onLogs", &onLogsFunc); 
​ 
​ 
   napi_create_reference(env, logListener, 1, &logListenerRef); 
   napi_create_reference(env, onLogsFunc, 1, &onLogsFuncRef); 
​ 
   return nullptr; 
}

3、将OnLogsListener 接口使用GlobalThis包装,(globalThis)在API10中不能使用了,换成其他的方式,使用单例模式,创建类似于GlobalThis的单例。

import hilog from '@ohos.hilog'; 
​ 
export class GlobalThisAdapter { 
 private constructor() { 
} 
​ 
 private static instance: GlobalThisAdapter; 
 private _logListener: LogsListener = new LogsListener(); 
​ 
 public static getInstance(): GlobalThisAdapter { 
   if (!GlobalThisAdapter.instance) { 
     GlobalThisAdapter.instance = new GlobalThisAdapter(); 
  } 
   return GlobalThisAdapter.instance; 
} 
​ 
 geLogsListener(): LogsListener | undefined { 
   return this._logListener; 
} 
​ 
 setLogsListener(value: LogsListener): void { 
   this._logListener = value; 
} 
}

4、获取单例,并将其通过注册接口的方法注册。注意这里是在UIAbility的onCreate生命周期就将globalThisAdapter注册,此处是将globalThisAdapter注册的,因为这样可以传递更多的信息,如果仅仅实现本功能建议直接注册LogsListener即可。

import testNapi from 'libentry.so'; 
import { GlobalThisAdapter } from '../pages/GlobalThisAdapter'; 
​ 
export default class EntryAbility extends UIAbility { 
 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 
   let globalThisAdapter: GlobalThisAdapter = GlobalThisAdapter.getInstance(); 
   testNapi.registerLogListener(globalThisAdapter); 
   hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 
} 
   //省略其他的代码 
}

5、调用其他的业务方法的时候从napi_ref中获取对应的onLogs,执行回调新增callOnLogs方法,当需要回调js的onLogs的方法的时候调用该方法即可

static void callOnLogs(napi_env env, LogLevel level, const char *message) { 
​ 
   size_t argc = 2; 
   napi_value argv[2] = {nullptr}; 
​ 
   napi_create_int32(env, level, &argv[0]); 
   napi_create_string_utf8(env, message, strlen(message) + 1, &argv[1]); 
   napi_value logListener = nullptr; 
   napi_value onLogsFunc = nullptr; 
   napi_get_reference_value(env, logListenerRef, &logListener); 
   napi_get_reference_value(env, onLogsFuncRef, &onLogsFunc); 
​ 
   napi_call_function(env, logListener, onLogsFunc, argc, argv, nullptr); 
}

在执行业务方法的时候,调用callOnlogs方法

static napi_value Add(napi_env env, napi_callback_info info) { 
   size_t requireArgc = 2; 
   size_t argc = 2; 
   napi_value args[2] = {nullptr}; 
​ 
   napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 
​ 
   napi_valuetype valuetype0; 
   napi_typeof(env, args[0], &valuetype0); 
​ 
   napi_valuetype valuetype1; 
   napi_typeof(env, args[1], &valuetype1); 
​ 
   double value0; 
   napi_get_value_double(env, args[0], &value0); 
​ 
   double value1; 
   napi_get_value_double(env, args[1], &value1); 
​ 
   napi_value sum; 
   //调用该方法即可实现回调 
   callOnLogs(env, LogLevel::INFO, "execute native Add function success"); 
​ 
   napi_create_double(env, Add(value0, value1), &sum); 
​ 
   return sum; 
}

适配的版本信息

IDE:DevEco Studio 4.0.1.601

SDK:HarmoneyOS 4.0.10.11

分享
微博
QQ
微信
回复
2024-05-24 21:35:22
相关问题
arktshashmap转为native
403浏览 • 1回复 待解决
Native调用ArkTS类函数
329浏览 • 1回复 待解决
NAPI执行上层时,如何获取env
679浏览 • 1回复 待解决
ArkTSNative如何进行map数据交互
773浏览 • 1回复 待解决
如何在Native释放ArkTS对象
783浏览 • 1回复 待解决
Native如何使用hilog打印出日志信息
875浏览 • 1回复 待解决
Native调用ArkTS的全局普通方法
339浏览 • 1回复 待解决
如何在Native构建一个ArkTS对象
662浏览 • 1回复 待解决
native的log获取不到
486浏览 • 1回复 待解决
Native如何打印char指针
596浏览 • 1回复 待解决
interface如何调用
437浏览 • 1回复 待解决
TS如何批量传递函数到native
351浏览 • 1回复 待解决
WebView页面加载错误能力。
291浏览 • 1回复 待解决
OpenHarmony idl如何实现异步
3181浏览 • 1回复 待解决
Emitter如何声明函数类型
468浏览 • 1回复 待解决