HarmonyOS鸿蒙Next中如何在子包中使用全局的Context
HarmonyOS鸿蒙Next中如何在子包中使用全局的Context 定义全局的 context
main_ability.cj:
var globalAbilityContext: Option<AbilityContext> = Option<AbilityContext>.None
class MainAbility <: Ability {
public init() {
super()
registerSelf()
}
public override func onCreate(want: Want, launchParam: LaunchParam): Unit {
AppLog.info("MainAbility OnCreated.${want.abilityName}")
globalAbilityContext = Option<AbilityContext>.Some(this.context);
match (launchParam.launchReason) {
case LaunchReason.START_ABILITY => AppLog.info("START_ABILITY")
case _ => ()
}
}
public override func onWindowStageCreate(windowStage: WindowStage): Unit {
AppLog.info("MainAbility onWindowStageCreate.")
let appStageContext = getStageContext(globalAbilityContext.getOrThrow());
DatabaseHelper(appStageContext)
windowStage.loadContent("EntryView")
}
}
func createAbility(): MainAbility {
MainAbility()
}
let ABILITY_REGISTER_RESULT = Ability.registerCreator("CangjieAbility", createAbility)
public func get_app_Context(): CPointer<Unit> {
return getStageContext(globalAbilityContext.getOrThrow())
}
定义了get_app_Context用来做全局的 context 使用,
在同一级,主包
package ohos_app_cangjie_entry
index.cj中定义了一个公共的方法,获取存储的值
//获取沙盒存储数据的值
public func getPreferencesInfo(key:String){
var my_preference = Preferences.getPreferences(get_app_Context(), CommonTagConstants.PRE_TAG);
if (my_preference.has(key)){
let value = my_preference.get(key,ValueType.string(''))
match (value) {
case ValueType.string(n) => return n
case _ => return ''
}
}
return ''
}
子包:
package ohos_app_cangjie_entry.databasemgr
子包的文件
BaseStoreQueryMgr.cj
package ohos_app_cangjie_entry.databasemgr
import ohos_app_cangjie_entry.getPreferencesInfo
import ohos_app_cangjie_entry.constants.CommonTagConstants
public class BaseStoreQueryMgr {
/**
* 查询今日路线门店数量
*/
public static func getTodayRouteStoreCount() {
let empId: String = getPreferencesInfo(CommonTagConstants.EMP_ID)
}
}
在同级的 index.cj ,login.cj 中使用没有报错,但是我在子包中使用,就报错,报错信息:Error: combined package ‘ohos_app_cangjie_entry’ is depended (directly or indirectly) by its sub package ‘ohos_app_cangjie_entry.databasemgr’, cannot combine it,如何解决这个依赖冲突
这是目录结构
更多关于HarmonyOS鸿蒙Next中如何在子包中使用全局的Context的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
cjpm.toml:仓颉模块配置文件,用于配置一些基础信息、依赖项、编译选项等内容,cjpm主要通过这个文件进行解析执行。其中,模块名可以在cjpm.toml中进行重命名,但是包名不能在cjpm.toml中进行重命名。
【问题定位】
根据报错信息,提示父包被子包依赖,无法combine。检查配置文件是否中启用了combined配置,若启用了该配置可能会出现无法通过导入关系识别的循环依赖,导致编译报错。
【分析结论】
启用了combined配置,不允许子包直接或者间接依赖父包,导致编译报错。
【修改建议】
- 查找并删除子包中存在的对父包的导入。
- 去掉模块里cjpm.toml中的combined配置:
[profile]
[profile.build]
incremental = true
lto = ""
# 关闭combined配置
# [profile.build.combined]
# ohos_app_cangjie_entry = "dynamic"
[profile.customized-option]
debug = "-g -Woff all"
release = "--fast-math -O2 -s -Woff all"
[profile.test]
更多关于HarmonyOS鸿蒙Next中如何在子包中使用全局的Context的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
通过单例可以实现获取全局的context,可以避免子包之间的相互引用
在HarmonyOS Next中,子包通过AbilityStage
获取全局Context。在模块的src/main/resources/module.json5
中配置"context"
字段,声明Context依赖。子包代码中调用AbilityStage.getContext()
获取全局上下文对象,该对象提供应用资源管理、系统服务调用等基础能力。子包与主包共享同一个进程空间时,可通过此方式直接访问全局上下文。
在HarmonyOS Next中,子包不能直接依赖主包,这会导致循环依赖错误。你的问题在于子包ohos_app_cangjie_entry.databasemgr
导入了主包ohos_app_cangjie_entry
中的getPreferencesInfo
函数。
解决方案:
- 将全局Context管理移到独立的共享模块
- 使用ArkTS的依赖注入机制
- 通过AbilityContext传递参数
推荐重构代码结构:
// 创建独立的context管理模块
public class AppContextManager {
private static var abilityContext: AbilityContext | null = null
public static setContext(context: AbilityContext) {
this.abilityContext = context
}
public static getContext(): AbilityContext {
return this.abilityContext
}
}
// 在MainAbility中设置
public override func onCreate(want: Want, launchParam: LaunchParam): Unit {
AppContextManager.setContext(this.context)
}
// 子包中直接使用AppContextManager
let context = AppContextManager.getContext()
这样避免了包之间的循环依赖,同时保持了Context的全局可用性。