HarmonyOS鸿蒙Next中为什么我的JNI_CalculateServiceWrappedImpl::GetInstance_jni方法中,jsThis_对象第二次返回到ts层后,就编程undefine了,都是同一个指针啊

HarmonyOS鸿蒙Next中为什么我的JNI_CalculateServiceWrappedImpl::GetInstance_jni方法中,jsThis_对象第二次返回到ts层后,就编程undefine了,都是同一个指针啊

ets代码

let calculateService1 = testNapi.CalculateServiceWrapped.GetInstance();
let calculateService2 = testNapi.CalculateServiceWrapped.GetInstance();
let calculateService3 = testNapi.CalculateServiceWrapped.GetInstance();

index.d.ts

export class CalculateServiceWrapped{
  private constructor();
  public static GetInstance() : CalculateServiceWrapped;
  public calculateNum(a:Number) : Number;
}

CalculateServiceWrapped

//
// Created on 2024/10/11.
//

#include "CalculateServiceWrapped.h"
#define LOG_TAG "napi_test"
#include "hilog/log.h"

static CalculateServiceWrapped* _instance = nullptr;

CalculateServiceWrapped::CalculateServiceWrapped(){
    
}

CalculateServiceWrapped* CalculateServiceWrapped::GetInstance()
{
    if(_instance == nullptr)
    {
        _instance = new CalculateServiceWrapped();
    }
    return _instance;
}

int CalculateServiceWrapped::calculateNum(int a){
    return a * a;
}
#include "jni_calculate_service_wrapped.h"
#include "src/CalculateServiceWrapped.h"
#include <string>

static thread_local napi_ref g_ref = nullptr;
napi_env JNI_CalculateServiceWrappedImpl::env_ = nullptr;
napi_value JNI_CalculateServiceWrappedImpl::jsThis_ = nullptr;
napi_ref JNI_CalculateServiceWrappedImpl::wrapper_ = nullptr;

napi_value JNI_CalculateServiceWrappedImpl::New(napi_env env, napi_callback_info info)
{
  napi_value newTarget;
  napi_get_new_target(env, info, &newTarget);
  if (newTarget != nullptr) {
    size_t argc = 1;
    napi_value args[1];
    napi_value jsThis;
    napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);

    CalculateServiceWrapped* obj = CalculateServiceWrapped::GetInstance();

    JNI_CalculateServiceWrappedImpl::env_ = env;
    JNI_CalculateServiceWrappedImpl::jsThis_ = jsThis;
    napi_wrap(env,
              jsThis,
              reinterpret_cast<void*>(obj),
              JNI_CalculateServiceWrappedImpl::Destructor,
              nullptr,  // finalize_hint
              &JNI_CalculateServiceWrappedImpl::wrapper_);

    return jsThis;
  } else {
    size_t argc = 0;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    napi_value cons;
    napi_get_reference_value(env, g_ref, &cons);
    napi_value instance;
    napi_new_instance(env, cons, argc, args, &instance);

    return instance;
  }
}

void JNI_CalculateServiceWrappedImpl::Destructor(napi_env env,
                          void* nativeObject,
                          [[maybe_unused]] void* finalize_hint)
{
}

napi_value JNI_CalculateServiceWrappedImpl::getJsObject()
{
    return this->jsThis_;
}

napi_value JNI_CalculateServiceWrappedImpl::GetInstance_jni(napi_env env, napi_callback_info info)
{
    if (jsThis_ == nullptr) 
    {
        auto obj = CalculateServiceWrapped::GetInstance();

        napi_property_descriptor properties[] = {
            { "GetInstance", nullptr, JNI_CalculateServiceWrappedImpl::GetInstance_jni, nullptr, nullptr, nullptr, napi_static, nullptr },
            { "calculateNum", nullptr, JNI_CalculateServiceWrappedImpl::calculateNum_jni, nullptr, nullptr, nullptr, napi_default, nullptr }
        };

        napi_value instance = nullptr;
        napi_create_object_with_properties(env, &instance, 2, properties);
    
        JNI_CalculateServiceWrappedImpl::env_ = env;
        JNI_CalculateServiceWrappedImpl::jsThis_ = instance;

        napi_wrap(env,
                  instance,
                  reinterpret_cast<void*>(obj),
                  JNI_CalculateServiceWrappedImpl::Destructor,
                  nullptr,  // finalize_hint
                  &JNI_CalculateServiceWrappedImpl::wrapper_);
    }
    return jsThis_;
}

napi_value JNI_CalculateServiceWrappedImpl::calculateNum_jni(napi_env env, napi_callback_info info)
{
    napi_value jsThis;
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);

    CalculateServiceWrapped *obj;
    napi_unwrap(env, jsThis, reinterpret_cast<void**>(&obj));

    int value1 = 0;
    napi_get_value_int32(env, args[0], &value1);
    
    auto tmpSelf = (CalculateServiceWrapped*)obj;
    int result = tmpSelf->calculateNum(value1);

    napi_value object;
    napi_create_int32(env, result, &object);
    
    return object;
}

napi_value JNI_CalculateServiceWrappedImpl::Init(napi_env env, napi_value exports)
{
    napi_property_descriptor properties[] = {
        { "GetInstance", nullptr, JNI_CalculateServiceWrappedImpl::GetInstance_jni, nullptr, nullptr, nullptr, napi_static, nullptr },
        { "calculateNum", nullptr, JNI_CalculateServiceWrappedImpl::calculateNum_jni, nullptr, nullptr, nullptr, napi_default, nullptr }
    };
    
    const char* class_name = "JNI_CalculateServiceWrappedImpl";
    napi_define_class(env, class_name, strlen(class_name), JNI_CalculateServiceWrappedImpl::New, nullptr, 2, properties, &cons);
    
    napi_set_named_property(env, exports, "CalculateServiceWrapped", cons);
    return exports;
}

更多关于HarmonyOS鸿蒙Next中为什么我的JNI_CalculateServiceWrappedImpl::GetInstance_jni方法中,jsThis_对象第二次返回到ts层后,就编程undefine了,都是同一个指针啊的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

您好,该问题已反馈研发人员进一步分析,请耐心等待

更多关于HarmonyOS鸿蒙Next中为什么我的JNI_CalculateServiceWrappedImpl::GetInstance_jni方法中,jsThis_对象第二次返回到ts层后,就编程undefine了,都是同一个指针啊的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你好,这个问题我也觉得非常诡异,之前你有看过。

我已经贴出代码了,有空麻烦看下哈。

https://developer.huawei.com/consumer/cn/forum/topic/0202163792205583915?fid=0109140870620153026

补充一个出问题的图,可以看到只有第一次能够获取到正确的句柄,后面两次都是undefined

cke_325.png

在HarmonyOS鸿蒙Next中,JNI_CalculateServiceWrappedImpl::GetInstance_jni方法中jsThis_对象第二次返回到TS层后变为undefined,可能是因为以下原因:

  1. JS对象生命周期管理:jsThis_对象在第一次返回到TS层时有效,但在第二次返回时可能已经被垃圾回收或引用丢失。鸿蒙的JS引擎可能在某些情况下自动回收不再使用的对象。

  2. JNI与JS绑定问题:jsThis_对象在JNI层与JS层的绑定可能出现了问题。如果jsThis_的引用在JNI层没有正确维护,或者JS层的引用计数机制未能正确识别该对象的持续使用,可能导致对象变为undefined

  3. 指针传递问题:虽然指针相同,但在传递过程中,JS引擎可能未正确识别该指针所指向的对象,导致对象在TS层被当作undefined处理。

  4. 跨语言调用机制:在JNI与JS的跨语言调用中,对象的状态管理可能存在问题。鸿蒙的跨语言调用机制可能在某些情况下无法正确维护对象的状态,导致对象在第二次返回时失效。

  5. JS引擎实现差异:不同版本的JS引擎在处理对象引用时可能存在差异,可能导致jsThis_对象在第二次返回时变为undefined

建议检查jsThis_对象在JNI层和JS层的引用管理,确保对象在跨语言调用过程中的状态正确维护。

在HarmonyOS鸿蒙Next中,JNI_CalculateServiceWrappedImpl::GetInstance_jni方法中jsThis_对象第二次返回到TS层后变为undefined,可能是由于以下原因:

  1. 生命周期管理问题:jsThis_对象可能在第一次调用后被垃圾回收,导致第二次引用时变为undefined。确保在JS层保持对jsThis_的引用。

  2. 跨语言调用问题:JNI调用可能导致对象引用丢失。检查JNI调用的正确性,确保对象在跨语言传递时未被意外释放。

  3. 缓存机制问题:如果使用了缓存机制,确保缓存的对象未被意外清除或覆盖。

建议检查对象生命周期管理、JNI调用逻辑以及缓存机制,确保对象在跨语言传递时保持有效。

回到顶部