1. 官方指导文档
2. 源码流程解析
2.1 获取DataAbilityHelper
从官网可以看到,DataAbilityHelper是从featureAbility中拿到的。开发者拿到DataAbilityHelper后,从而对DataAbility进行操作。
由于整个流程涉及到AbilityMS,BundleMS,AppMS,用户进程AbilityKit,AppSpwan等多个进程或者服务之间的交互,我这边简化了流程,仅把DataAbility相关的处理做了回执。
下面对上面的流程图做一下详细介绍
2.1.1 从featureAbility进入napi
通过feature_ability.cpp我们看到acquireDataAbilityHelper对应NAPI_AcquireDataAbilityHelper方法。
napi_value FeatureAbilityInit(napi_env env, napi_value exports)
{
HILOG_INFO("%{public}s,called", __func__);
napi_property_descriptor properties[] = {
DECLARE_NAPI_FUNCTION("startAbility", NAPI_StartAbility),
DECLARE_NAPI_FUNCTION("startAbilityForResult", NAPI_StartAbilityForResult),
DECLARE_NAPI_FUNCTION("finishWithResult", NAPI_SetResult),
DECLARE_NAPI_FUNCTION("terminateSelfWithResult", NAPI_SetResult),
DECLARE_NAPI_FUNCTION("terminateAbility", NAPI_TerminateAbility),
DECLARE_NAPI_FUNCTION("terminateSelf", NAPI_TerminateAbility),
DECLARE_NAPI_FUNCTION("hasWindowFocus", NAPI_HasWindowFocus),
DECLARE_NAPI_FUNCTION("getContext", NAPI_GetContext),
DECLARE_NAPI_FUNCTION("getWant", NAPI_GetWant),
DECLARE_NAPI_FUNCTION("getAppType", NAPI_GetAppType),
DECLARE_NAPI_FUNCTION("getAbilityName", NAPI_GetAbilityName),
DECLARE_NAPI_FUNCTION("getAbilityInfo", NAPI_GetAbilityInfo),
DECLARE_NAPI_FUNCTION("getHapModuleInfo", NAPI_GetHapModuleInfo),
DECLARE_NAPI_FUNCTION("getDataAbilityHelper", NAPI_GetDataAbilityHelper),
DECLARE_NAPI_FUNCTION("acquireDataAbilityHelper", NAPI_AcquireDataAbilityHelper),
DECLARE_NAPI_FUNCTION("connectAbility", NAPI_FAConnectAbility),
DECLARE_NAPI_FUNCTION("disconnectAbility", NAPI_FADisConnectAbility),
DECLARE_NAPI_FUNCTION("continueAbility", NAPI_FAContinueAbility),
DECLARE_NAPI_FUNCTION("getWantSync", NAPI_GetWantSync),
DECLARE_NAPI_FUNCTION("setShowOnLockScreen", NAPI_SetShowOnLockScreen),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
return exports;
}
而NAPI_AcquireDataAbilityHelper未做任何处理又调用到了napi_common_ability.cpp中的NAPI_AcquireDataAbilityHelperCommon,NAPI_AcquireDataAbilityHelperCommon基本上也无重要处理,又调用到了AcquireDataAbilityHelperWrap
napi_value AcquireDataAbilityHelperWrap(napi_env env, napi_callback_info info, DataAbilityHelperCB *dataAbilityHelperCB)
{
HILOG_INFO("%{public}s,called", __func__);
if (dataAbilityHelperCB == nullptr) {
HILOG_ERROR("%{public}s,dataAbilityHelperCB == nullptr", __func__);
return nullptr;
}
size_t requireArgc = ARGS_ONE;
size_t argc = ARGS_ONE;
napi_value args[ARGS_ONE] = {nullptr};
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
if (argc > requireArgc) {
HILOG_ERROR("%{public}s, Wrong argument count.", __func__);
return nullptr;
}
napi_valuetype valuetype = napi_undefined;
NAPI_CALL(env, napi_typeof(env, args[PARAM0], &valuetype));
if (valuetype != napi_string) {
HILOG_ERROR("%{public}s, Wrong argument type.", __func__);
return nullptr;
}
if (!CheckAbilityType(&dataAbilityHelperCB->cbBase)) {
dataAbilityHelperCB->cbBase.errCode = NAPI_ERR_ABILITY_TYPE_INVALID;
HILOG_ERROR("%{public}s ability type invalid.", __func__);
return nullptr;
}
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, *(GetGlobalDataAbilityHelper()), 1, &args[PARAM0], &result));
if (!IsTypeForNapiValue(env, result, napi_object)) {
HILOG_ERROR("%{public}s, IsTypeForNapiValue retval is false", __func__);
return nullptr;
}
delete dataAbilityHelperCB;
dataAbilityHelperCB = nullptr;
HILOG_INFO("%{public}s,end", __func__);
return result;
}
这里面主要是拿到入参uri然后创建Napi层的DataAbilityHelper实例。
napi_data_ability_helper.cpp的DataAbilityHelperConstructor
napi_value DataAbilityHelperConstructor(napi_env env, napi_callback_info info)
{
HILOG_INFO("%{public}s,called", __func__);
size_t argc = 1;
napi_value argv[1] = {nullptr};
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
NAPI_ASSERT(env, argc > 0, "Wrong number of arguments");
std::string strUri = NapiValueToStringUtf8(env, argv[0]);
napi_value global = nullptr;
NAPI_CALL(env, napi_get_global(env, &global));
napi_value abilityObj = nullptr;
NAPI_CALL(env, napi_get_named_property(env, global, "ability", &abilityObj));
Ability *ability = nullptr;
NAPI_CALL(env, napi_get_value_external(env, abilityObj, (void **)&ability));
HILOG_INFO("ability = %{public}p strUri = %{public}s", ability, strUri.c_str());
HILOG_INFO("dataAbilityHelperList.size = %{public}zu", g_dataAbilityHelperList.size());
std::shared_ptr<DataAbilityHelper> dataAbilityHelper =
DataAbilityHelper::Creator(ability->GetContext(), std::make_shared<Uri>(strUri));
if (dataAbilityHelper == nullptr) {
HILOG_INFO("%{public}s, dataAbilityHelper is nullptr", __func__);
return nullptr;
}
HILOG_INFO("dataAbilityHelper = %{public}p", dataAbilityHelper.get());
g_dataAbilityHelperList.emplace_back(dataAbilityHelper);
HILOG_INFO("dataAbilityHelperList.size = %{public}zu", g_dataAbilityHelperList.size());
napi_wrap(
env,
thisVar,
dataAbilityHelper.get(),
[](napi_env env, void *data, void *hint) {
DataAbilityHelper *objectInfo = static_cast<DataAbilityHelper *>(data);
HILOG_INFO("DAHelper finalize_cb objectInfo = %{public}p", objectInfo);
HILOG_INFO("DAHelper finalize_cb regInstances_.size = %{public}zu", registerInstances_.size());
auto helper = std::find_if(registerInstances_.begin(),
registerInstances_.end(),
[&objectInfo](const DAHelperOnOffCB *helper) { return helper->dataAbilityHelper == objectInfo; });
if (helper != registerInstances_.end()) {
HILOG_INFO("DataAbilityHelper finalize_cb find helper");
(*helper)->dataAbilityHelper->Release();
delete *helper;
registerInstances_.erase(helper);
}
HILOG_INFO("DAHelper finalize_cb regInstances_.size = %{public}zu", registerInstances_.size());
g_dataAbilityHelperList.remove_if(
[objectInfo](const std::shared_ptr<DataAbilityHelper> &dataAbilityHelper) {
return objectInfo == dataAbilityHelper.get();
});
HILOG_INFO("DAHelper finalize_cb dataAbilityHelperList.size = %{public}zu", g_dataAbilityHelperList.size());
},
nullptr,
nullptr);
HILOG_INFO("%{public}s,called end", __func__);
return thisVar;
}
创建DataAbilityHelper的时候又会使用C++层的DataAblityHelper的Creator方法创建实例。
std::shared_ptr<DataAbilityHelper> DataAbilityHelper::Creator(
const std::shared_ptr<Context> &context, const std::shared_ptr<Uri> &uri)
{
APP_LOGI("DataAbilityHelper::Creator with context uri called.");
return DataAbilityHelper::Creator(context, uri, false);
}
2.1.2 c++层DataAblityHelper的创建
DataAbilityHelper的Creator会先调用到AbilityManagerClient.AcquireDataAbility(),然后到AbilityManagerService.AcquireDataAbility(),最后会到DataAbilityManager.Acquire()。
sptr<IAbilityScheduler> DataAbilityManager::Acquire(
const AbilityRequest &abilityRequest, bool tryBind, const sptr<IRemoteObject> &client, bool isSystem)
{
HILOG_DEBUG("%{public}s(%{public}d)", __PRETTY_FUNCTION__, __LINE__);
if (abilityRequest.abilityInfo.type != AppExecFwk::AbilityType::DATA) {
HILOG_ERROR("Data ability manager acquire: not a data ability.");
return nullptr;
}
if (abilityRequest.abilityInfo.bundleName.empty() || abilityRequest.abilityInfo.name.empty()) {
HILOG_ERROR("Data ability manager acquire: invalid name.");
return nullptr;
}
std::shared_ptr<AbilityRecord> clientAbilityRecord;
const std::string dataAbilityName(abilityRequest.abilityInfo.bundleName + '.' + abilityRequest.abilityInfo.name);
if (client && !isSystem) {
clientAbilityRecord = Token::GetAbilityRecordByToken(client);
if (!clientAbilityRecord) {
HILOG_ERROR("Data ability manager acquire: invalid client token.");
return nullptr;
}
HILOG_INFO("Ability '%{public}s' acquiring data ability '%{public}s'...",
clientAbilityRecord->GetAbilityInfo().name.c_str(),
dataAbilityName.c_str());
} else {
HILOG_INFO("Loading data ability '%{public}s'...", dataAbilityName.c_str());
}
std::lock_guard<std::mutex> locker(mutex_);
if (DEBUG_ENABLED) {
DumpLocked(__func__, __LINE__);
}
DataAbilityRecordPtr dataAbilityRecord;
auto it = dataAbilityRecordsLoaded_.find(dataAbilityName);
if (it == dataAbilityRecordsLoaded_.end()) {
HILOG_DEBUG("Acquiring data ability is not existed, loading...");
dataAbilityRecord = LoadLocked(dataAbilityName, abilityRequest);
if (!dataAbilityRecord) {
HILOG_ERROR("Failed to load data ability '%{public}s'.", dataAbilityName.c_str());
return nullptr;
}
} else {
HILOG_DEBUG("Acquiring data ability is existed .");
dataAbilityRecord = it->second;
}
auto scheduler = dataAbilityRecord->GetScheduler();
if (!scheduler) {
if (DEBUG_ENABLED) {
HILOG_ERROR("BUG: data ability '%{public}s' is not loaded, removing it...", dataAbilityName.c_str());
}
auto it = dataAbilityRecordsLoaded_.find(dataAbilityName);
if (it != dataAbilityRecordsLoaded_.end()) {
dataAbilityRecordsLoaded_.erase(it);
}
return nullptr;
}
if (client) {
dataAbilityRecord->AddClient(client, tryBind, isSystem);
}
if (DEBUG_ENABLED) {
DumpLocked(__func__, __LINE__);
}
return scheduler;
}
上述代码会做这么几件事:
- 根据bundleName和abilityName去查找是否已经存在对应的DataAbility实例
- 如果没找到的话会先去创建对应的DataAbility,以及DataAbilityRecord(记录DataAbility实例、DataAbility的IAbilityScheduler、以及所有的Client)
- 把DataAbilityRecord以及客户端信息记录下来并且把IAbilityScheduler返回给调用方
这样的话,客户端就已经拿到了DataAbility的IAbilityScheduler对象,接下来,把IAbilityScheduler封装在DataAbilityHelper中返回出去。
2.2 DataAbilityHelper的释放
当超过变量的生命周期时,DataAbilityHelper会进行释放,此时会调用dataAbilityHelper.Release()
napi_wrap(
env,
thisVar,
dataAbilityHelper.get(),
[](napi_env env, void *data, void *hint) {
DataAbilityHelper *objectInfo = static_cast<DataAbilityHelper *>(data);
HILOG_INFO("DAHelper finalize_cb objectInfo = %{public}p", objectInfo);
HILOG_INFO("DAHelper finalize_cb regInstances_.size = %{public}zu", registerInstances_.size());
auto helper = std::find_if(registerInstances_.begin(),
registerInstances_.end(),
[&objectInfo](const DAHelperOnOffCB *helper) { return helper->dataAbilityHelper == objectInfo; });
if (helper != registerInstances_.end()) {
HILOG_INFO("DataAbilityHelper finalize_cb find helper");
(*helper)->dataAbilityHelper->Release();
delete *helper;
registerInstances_.erase(helper);
}
HILOG_INFO("DAHelper finalize_cb regInstances_.size = %{public}zu", registerInstances_.size());
g_dataAbilityHelperList.remove_if(
[objectInfo](const std::shared_ptr<DataAbilityHelper> &dataAbilityHelper) {
return objectInfo == dataAbilityHelper.get();
});
HILOG_INFO("DAHelper finalize_cb dataAbilityHelperList.size = %{public}zu", g_dataAbilityHelperList.size());
},
nullptr,
nullptr);
然后就会调用AbilityManagerClient.ReleaseDataAbility(),接着会到AbilityManagerService.ReleaseDataAbility(),接着会到DataAbilityManager.Release()。
int DataAbilityManager::Release(
const sptr<IAbilityScheduler> &scheduler, const sptr<IRemoteObject> &client, bool isSystem)
{
HILOG_DEBUG("%{public}s(%{public}d)", __PRETTY_FUNCTION__, __LINE__);
CHECK_POINTER_AND_RETURN(scheduler, ERR_NULL_OBJECT);
CHECK_POINTER_AND_RETURN(client, ERR_NULL_OBJECT);
std::lock_guard<std::mutex> locker(mutex_);
if (DEBUG_ENABLED) {
DumpLocked(__func__, __LINE__);
}
DataAbilityRecordPtrMap::iterator it;
DataAbilityRecordPtr dataAbilityRecord;
for (it = dataAbilityRecordsLoaded_.begin(); it != dataAbilityRecordsLoaded_.end(); ++it) {
if (it->second->GetScheduler() != nullptr && it->second->GetScheduler()->AsObject() == scheduler->AsObject()) {
dataAbilityRecord = it->second;
break;
}
}
if (!dataAbilityRecord) {
HILOG_ERROR("Releasing not existed data ability.");
return ERR_UNKNOWN_OBJECT;
}
auto abilityRecord = dataAbilityRecord->GetAbilityRecord();
CHECK_POINTER_AND_RETURN(abilityRecord, ERR_UNKNOWN_OBJECT);
int result = AbilityUtil::JudgeAbilityVisibleControl(abilityRecord->GetAbilityInfo());
if (result != ERR_OK) {
HILOG_ERROR("%{public}s JudgeAbilityVisibleControl error.", __func__);
return result;
}
if (dataAbilityRecord->GetClientCount(client) == 0) {
HILOG_ERROR("Release data ability with wrong client.");
return ERR_UNKNOWN_OBJECT;
}
HILOG_INFO("Releasing data ability '%{public}s'...", it->first.c_str());
dataAbilityRecord->RemoveClient(client, isSystem);
if (DEBUG_ENABLED) {
DumpLocked(__func__, __LINE__);
}
return ERR_OK;
}
上述代码主要做了这么几件事:
- 删除客户端的连接信息
- 如果当前DataAbility没有连接的话,去尝试将整个应用移动到后台