HarmonyOS 鸿蒙Next单例中存在上下文 线程中获取不到上下文 单例无法使用
HarmonyOS 鸿蒙Next单例中存在上下文 线程中获取不到上下文 单例无法使用 下面是我向华为提的单,我定义了一个用户持久化的类,需要传入上下文才能够获取单例。但是线程拿不到UI主线程的上下文,有大神有办法解决吗?不行的话我得改好多代码,看起来鸿蒙的多并发模型是封闭独立于JS引擎层的。
这是我的提单:
您好,我在android代码迁移到鸿蒙代码的过程中,定义了一个全局单例,单例中实现了用户持久化保存用户ID的方法,此单例必须传入上下文才能够获取实例。在worker线程中,由于worker线程获取不到UI主线程的context,导致我们无法在线程中使用这个单例,我们发现程序不报错但是阻塞在线程获取context的步骤,我们尝试过GlobalContext的方式,均无用,我们注意到文档中
-
当前支持序列化传输的Native绑定对象主要包含:Context和RemoteObject,但是我们没有native的开发经验 这部分文档没有序列化传输context的demo,这种方案可行吗?
-
还有我们注意到后续beta版本推出的@Sendable 这个装饰器后续支持的对象引用是否能够向其他线程传入上下文呢?
更多关于HarmonyOS 鸿蒙Next单例中存在上下文 线程中获取不到上下文 单例无法使用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
试试globalThis呢?
更多关于HarmonyOS 鸿蒙Next单例中存在上下文 线程中获取不到上下文 单例无法使用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
新的API已经停了。我用了官方demo里的GlobalContext
还是不行。
包括我把类构造函数接收context->
类构造函数直接接收this.mPreferences
仍然不行。我想是因为链入了context
阻塞在寻找context
的内存地址了。
if (this.mPreferences === undefined) {
this.mPreferences = preferences.getPreferencesSync(this.mContext, this.options);
}
GlobalContext
:
// @Sendable
export class GlobalContext {
private constructor() {}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
getObject(value: string): Object | undefined {
return this._objects.get(value);
}
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
解决了!
传context在安卓中是常用的招儿,鸿蒙还没试过,你也可以在那个持久类中声明一个
context: UIAbilityContext; 试试,初始化时看有没可能传过去,纯属探索,反正试试不会烧电脑:)
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
解决了 确实能传 但是要注意。原先上下文声明我是这么写的:
class A{
mContext: common.UIAbilityContext | null = null;
public configSDK(context: common.UIAbilityContext): void {
this.mContext = context;
};
}
但是这样我发现我的持久化还是获取不到实例
原:同步获取:
if (this.mPreferences === undefined) {
this.mPreferences = preferences.getPreferencesSync(this.mContext!, this.options); // 同步
}
改:异步获取:
if (this.mPreferences === undefined) {
this.mPreferences = await preferences.getPreferences(this.mContext!, this.options); // 异步
}
这样就解决了在线程里获取单例然后再获取用户持久化实例的问题,不过我还是没理解为啥同步不行?因为线程安全机制吗?我是菜鸡我不懂。能跑了 我的代码不用大改了,接下来就是把android共享内存的线程模型想办法迁移到鸿蒙了。
鸿蒙编程中一个巨大的隐藏问题就是以同步思维使用异步方法,出错了都不知道为何,要明白先得转换思维:简单讲就是当你调用现在新的(大多为异步的)API方法时,不能预期执行完你的代码语句就得到结果,所以赋值语句中用个异步方法,预期其返回值可赋值给变量时,这就已经错了,往往得到了空结果,加上await将这个异步方法的返回推迟到真正返回结果时再赋值,则可以得到正确结果,原因非常简单,但是没明白异步方法和同步方法的区别,还用同步的思维去调用异步方法往往就是错得不明不白。
如果用异步编程的思路考虑,用户持久化类的操作也可考虑不在单独线程中执行,直接在UI主线程中执行即可避免此类问题。用线程的担心主要是基于耗时操作阻塞UI线程造成ANR,但异步方法本身已经基本避免这种阻塞的发生,所以放在一个线程中基本影响不大。具体异步后台实现原理不太清楚,但估计UI操作优先级较高,其它耗时操作以队列排序执行,且优先级低于UI相关代码,因此,只要处理代码以异步方式编写,不分线程也不会有之前UI反应迟钝的问题。不知道此持久化操作负载多大,仅个人理解,非官方说明,有错勿喷:)
在HarmonyOS(鸿蒙)系统中,如果单例中存在上下文(Context),但在线程中无法获取到该上下文,导致单例无法使用,这通常是因为上下文与线程的生命周期或作用域不匹配。
鸿蒙系统中的上下文(Context)通常与特定的组件(如Activity、Service等)相关联,这些组件有自己的生命周期。当从单例中尝试访问与某个组件绑定的上下文时,如果该组件已经销毁或尚未创建,上下文将不可用。
在多线程环境中,如果线程尝试访问单例中的上下文,而该上下文实际上是与创建单例时的线程(通常是主线程)绑定的,那么在线程中就可能无法正确获取到该上下文。
解决这类问题的一种方法是确保上下文在需要时是可用的,并且与线程的生命周期相匹配。例如,可以通过以下方式:
- 传递上下文:在线程创建时,显式地将所需的上下文作为参数传递给线程。
- 使用应用上下文:如果上下文不需要与特定的组件生命周期绑定,可以考虑使用
getApplicationContext()
获取的应用上下文。 - 线程同步:确保在访问上下文时,相关的组件仍然处于活动状态,或者通过适当的同步机制来保护对上下文的访问。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html