3.1 Release preferences.getAll()调用失败问题分析报告
3.1 Release preferences.getAll()调用失败问题分析报告 1 关键字 3.1 Release;preferences.getAll() 2 问题描述 开发板型号:rk3568 OH版本:OpenHarmony 3.1 Release 问题现象:'@ohos.data.preferences'模块下的getAll方法调用失败,报错为不可调用。 3 问题原因 3.
1 关键字
3.1 Release;preferences.getAll()
2 问题描述
开发板型号:rk3568
OH版本:OpenHarmony 3.1 Release
问题现象:'@ohos.data.preferences'模块下的getAll方法调用失败,报错为不可调用。
3 问题原因
3.1 正常机制
调用'@ohos.data.preferences'模块下的getAll方法,从Preferences实例中获取含有所有键值的Object对象,正常回调并打印出Object对象值。
3.2 异常机制
调用'@ohos.data.preferences'模块下的getAll方法,从Preferences实例中获取含有所有键值的Object对象时,getAll方法调用失败并报错:不可调用。
4 解决方案
修改3.1 Release OpenHarmony源码来解决此问题。
在foundation\distributeddatamgr\appdatamgr\frameworks\jskitsimpl\napi_preferences\include\napi_preferences.h文件中添加GetAll定义。
private:
...
static napi_value GetAll(napi_env env, napi_callback_info info);
...
};
在foundation\distributeddatamgr\appdatamgr\frameworks\jskitsimpl\napi_preferences\src\napi_preferences.cpp文件中作如下改动:
-
引入头文件。
#include "js_utils.h"
-
在PreferencesProxy::Init中添加GetAll方法注入。
void PreferencesProxy::Init(napi_env env, napi_value exports)
{
napi_property_descriptor descriptors[] = {
...
DECLARE_NAPI_FUNCTION("getAll", GetAll),
...
};
...
}
-
在PreferencesAysncContext : NapiAsyncProxy结构体中添加allElements字段定义。
struct PreferencesAysncContext : NapiAsyncProxy<PreferencesAysncContext>::AysncContext {
...
std::map<std::string, PreferencesValue> allElements;
...
};
-
添加GetAll方法的实现。
//添加GetAll方法
napi_value PreferencesProxy::GetAll(napi_env env, napi_callback_info info)
{
NapiAsyncProxy<PreferencesAysncContext> proxy;
proxy.Init(env, info);
std::vector<NapiAsyncProxy<PreferencesAysncContext>::InputParser> parsers;
proxy.ParseInputs(parsers);
return proxy.DoAsyncWork(
"GetAll",
[](PreferencesAysncContext *asyncContext) {
PreferencesProxy *obj = reinterpret_cast<PreferencesProxy *>(asyncContext->boundObj);
asyncContext->allElements = obj->value_->GetAll();
return OK;
},
GetAllExecute);
}
//补充GetAllExecute方法
int32_t GetAllExecute(PreferencesAysncContext *asyncContext, napi_value &output)
{
LOG_ERROR("PreferencesProxy::GetAllExecute start");
if (napi_create_object(asyncContext->env, &output) != napi_ok) {
LOG_ERROR("PreferencesProxy::GetAll creat object failed");
return ERR;
}
napi_value jsVal = nullptr;
for (const auto &[key, value] : asyncContext->allElements) {
PreferencesValue val = value;
if (val.IsBool()) {
jsVal = JSUtils::Convert2JSValue(asyncContext->env, (bool)val);
if (nullptr == jsVal) {
LOG_ERROR("PreferencesProxy::GetAll get property bool failed");
return ERR;
}
if (napi_set_named_property(asyncContext->env, output, key.c_str(), jsVal) != napi_ok) {
LOG_ERROR("PreferencesProxy::GetAll set property bool failed");
return ERR;
}
} else if (val.IsDouble()) {
jsVal = JSUtils::Convert2JSValue(asyncContext->env, (double)val);
if (nullptr == jsVal) {
LOG_ERROR("PreferencesProxy::GetAll get property double failed");
return ERR;
}
if (napi_set_named_property(asyncContext->env, output, key.c_str(), jsVal) != napi_ok) {
LOG_ERROR("PreferencesProxy::GetAll set property double failed");
return ERR;
}
} else if (val.IsString()) {
std::string tempStr = (std::string)val;
jsVal = JSUtils::Convert2JSValue(asyncContext->env, tempStr);
if (nullptr == jsVal) {
LOG_ERROR("PreferencesProxy::GetAll get property string failed");
return ERR;
}
if (napi_set_named_property(asyncContext->env, output, key.c_str(), jsVal) != napi_ok) {
LOG_ERROR("PreferencesProxy::GetAll set property string failed");
return ERR;
}
} else {
LOG_ERROR("PreferencesProxy::GetAll other property ");
}
}
LOG_ERROR("PreferencesProxy::GetAllExecute end");
return OK;
}
按照以上步骤修改后,preferences.getAll()可以正常回调了。
5 定位过程
-
通过日志查看,在设备的3.2 Beta3版本中,getAll方法正常回调并打印所有键值的Object对象,而在设备的3.1 Release版本getAll方法回调失败,报错为不可调用,推测3.1 Release版本中没有定义getAll方法。
-
查看源码的napi_preferences.cpp文件,发现3.1 Release版本没有声明getAll方法,而3.2 Beta3版本声明了。参照3.2 Beta3版本,在3.1 Release版本中添加getAll的定义与方法实现。
6 知识分享
'@ohos.data.preferences'模块是从3.2 Beta1版本开始引入的,3.1 Relese版本对应的SDK文件中没有声明该模块。
更多推荐


所有评论(0)