diff --git a/doric-android/doric/src/main/java/pub/doric/DoricContext.java b/doric-android/doric/src/main/java/pub/doric/DoricContext.java index 3cc26334..3a267c47 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricContext.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricContext.java @@ -288,4 +288,8 @@ public class DoricContext { } } } + + public void onEnvChanged() { + callEntity(DoricConstant.DORIC_ENTITY_ENV_CHANGE); + } } diff --git a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java index 4bb56eb6..3282ee62 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import pub.doric.engine.DoricJSEngine; import pub.doric.plugin.AnimatePlugin; import pub.doric.plugin.CoordinatorPlugin; import pub.doric.plugin.DoricJavaPlugin; @@ -72,8 +73,6 @@ public class DoricRegistry { private static final Map bundles = new ConcurrentHashMap<>(); private static final Set doricLibraries = new HashSet<>(); private static final List> registries = new ArrayList<>(); - private final Map extendedEnvValues = new HashMap<>(); - private final Map> pluginInfoMap = new HashMap<>(); private final Map> nodeInfoMap = new HashMap<>(); @@ -99,7 +98,10 @@ public class DoricRegistry { } } - public DoricRegistry() { + private final WeakReference doricJSEngineWeakReference; + + public DoricRegistry(DoricJSEngine doricJSEngine) { + doricJSEngineWeakReference = new WeakReference<>(doricJSEngine); this.registerNativePlugin(ShaderPlugin.class); this.registerNativePlugin(ModalPlugin.class); this.registerNativePlugin(NetworkPlugin.class); @@ -168,11 +170,11 @@ public class DoricRegistry { } public void setEnvironmentVariable(String key, Object val) { - extendedEnvValues.put(key, val); - } - - public Map getEnvironmentVariables() { - return extendedEnvValues; + DoricJSEngine doricJSEngine = doricJSEngineWeakReference.get(); + if (doricJSEngine == null) { + return; + } + doricJSEngine.setEnvironmentVariable(key, val); } public void registerMonitor(IDoricMonitor monitor) { diff --git a/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java b/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java index 86654ffd..80ac93cb 100644 --- a/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java +++ b/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java @@ -34,11 +34,12 @@ import com.github.pengfeizhou.jscore.JavaFunction; import com.github.pengfeizhou.jscore.JavaValue; import java.util.ArrayList; -import java.util.Locale; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import pub.doric.Doric; import pub.doric.DoricContext; +import pub.doric.DoricContextManager; import pub.doric.DoricRegistry; import pub.doric.IDoricMonitor; import pub.doric.extension.bridge.DoricBridgeExtension; @@ -59,8 +60,9 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time private final DoricBridgeExtension mDoricBridgeExtension = new DoricBridgeExtension(); protected IDoricJSE mDoricJSE; private final DoricTimerExtension mTimerExtension; - private final DoricRegistry mDoricRegistry = new DoricRegistry(); - private final JSONBuilder mEnvironment = new JSONBuilder(); + private final DoricRegistry mDoricRegistry = new DoricRegistry(this); + private final Map mEnvironmentMap = new ConcurrentHashMap<>(); + private boolean initialized = false; public DoricJSEngine() { handlerThread = new HandlerThread(this.getClass().getSimpleName()); @@ -73,6 +75,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time initJSEngine(); injectGlobal(); initDoricRuntime(); + initialized = true; } }); mTimerExtension = new DoricTimerExtension(looper, this); @@ -87,6 +90,26 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time mDoricJSE = new DoricNativeJSExecutor(); } + public void setEnvironmentVariable(String key, Object v) { + mEnvironmentMap.put(key, v); + if (initialized) { + final JSONBuilder jsonBuilder = new JSONBuilder(); + for (String k : mEnvironmentMap.keySet()) { + jsonBuilder.put(k, mEnvironmentMap.get(k)); + } + mJSHandler.post(new Runnable() { + @Override + public void run() { + mDoricJSE.injectGlobalJSObject(DoricConstant.INJECT_ENVIRONMENT, + new JavaValue(jsonBuilder.toJSONObject())); + } + }); + for(DoricContext context:DoricContextManager.aliveContexts()){ + context.onEnvChanged(); + } + } + } + private void injectGlobal() { String appName = ""; String appVersion = ""; @@ -101,29 +124,26 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time } catch (Exception e) { e.printStackTrace(); } - mEnvironment - .put("platform", "Android") - .put("platformVersion", String.valueOf(android.os.Build.VERSION.SDK_INT)) - .put("appName", appName) - .put("appVersion", appVersion) - .put("screenWidth", DoricUtils.px2dp(DoricUtils.getScreenWidth())) - .put("screenHeight", DoricUtils.px2dp(DoricUtils.getScreenHeight())) - .put("screenScale", DoricUtils.getScreenScale()) - .put("statusBarHeight", DoricUtils.px2dp(DoricUtils.getStatusBarHeight())) - .put("hasNotch", false) - .put("deviceBrand", Build.BRAND) - .put("deviceModel", Build.MODEL) - .put("localeLanguage", context.getResources().getConfiguration().locale.getLanguage()) - .put("localeCountry", context.getResources().getConfiguration().locale.getCountry()); + mEnvironmentMap.put("platform", "Android"); + mEnvironmentMap.put("platformVersion", String.valueOf(android.os.Build.VERSION.SDK_INT)); + mEnvironmentMap.put("appName", appName); + mEnvironmentMap.put("appVersion", appVersion); + mEnvironmentMap.put("screenWidth", DoricUtils.px2dp(DoricUtils.getScreenWidth())); + mEnvironmentMap.put("screenHeight", DoricUtils.px2dp(DoricUtils.getScreenHeight())); + mEnvironmentMap.put("screenScale", DoricUtils.getScreenScale()); + mEnvironmentMap.put("statusBarHeight", DoricUtils.px2dp(DoricUtils.getStatusBarHeight())); + mEnvironmentMap.put("hasNotch", false); + mEnvironmentMap.put("deviceBrand", Build.BRAND); + mEnvironmentMap.put("deviceModel", Build.MODEL); + mEnvironmentMap.put("localeLanguage", context.getResources().getConfiguration().locale.getLanguage()); + mEnvironmentMap.put("localeCountry", context.getResources().getConfiguration().locale.getCountry()); - Map extend = mDoricRegistry.getEnvironmentVariables(); - for (String key : extend.keySet()) { - mEnvironment.put(key, extend.get(key)); + JSONBuilder jsonBuilder = new JSONBuilder(); + for (String key : mEnvironmentMap.keySet()) { + jsonBuilder.put(key, mEnvironmentMap.get(key)); } - mDoricJSE.injectGlobalJSObject(DoricConstant.INJECT_ENVIRONMENT, - new JavaValue(mEnvironment.toJSONObject())); - + new JavaValue(jsonBuilder.toJSONObject())); mDoricJSE.injectGlobalJSFunction(DoricConstant.INJECT_LOG, new JavaFunction() { @Override public JavaValue exec(JSDecoder[] args) { diff --git a/doric-android/doric/src/main/java/pub/doric/utils/DoricConstant.java b/doric-android/doric/src/main/java/pub/doric/utils/DoricConstant.java index 99bdd791..42b7ed4e 100644 --- a/doric-android/doric/src/main/java/pub/doric/utils/DoricConstant.java +++ b/doric-android/doric/src/main/java/pub/doric/utils/DoricConstant.java @@ -73,4 +73,5 @@ public class DoricConstant { public static final String DORIC_ENTITY_SHOW = "__onShow__"; public static final String DORIC_ENTITY_HIDDEN = "__onHidden__"; public static final String DORIC_ENTITY_BUILD = "__build__"; + public static final String DORIC_ENTITY_ENV_CHANGE = "__onEnvChanged__"; } diff --git a/doric-iOS/Pod/Classes/DoricContext.h b/doric-iOS/Pod/Classes/DoricContext.h index 8d05d356..92235616 100644 --- a/doric-iOS/Pod/Classes/DoricContext.h +++ b/doric-iOS/Pod/Classes/DoricContext.h @@ -63,6 +63,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)onHidden; +-(void)onEnvChanged; + - (DoricViewNode *)targetViewNode:(NSString *)viewId; - (void)dispatchToMainQueue:(_Nonnull dispatch_block_t)block; diff --git a/doric-iOS/Pod/Classes/DoricContext.m b/doric-iOS/Pod/Classes/DoricContext.m index 1495ab04..3f2be3e7 100644 --- a/doric-iOS/Pod/Classes/DoricContext.m +++ b/doric-iOS/Pod/Classes/DoricContext.m @@ -121,6 +121,10 @@ - (void)onHidden { [self callEntity:DORIC_ENTITY_HIDDEN withArgumentsArray:@[]]; } +- (void)onEnvChanged { + [self callEntity:DORIC_ENTITY_ENV_CHANGE withArgumentsArray:@[]]; +} + - (UIViewController *)vc { if (!_vc) { return [UIApplication sharedApplication].keyWindow.rootViewController; diff --git a/doric-iOS/Pod/Classes/DoricRegistry.h b/doric-iOS/Pod/Classes/DoricRegistry.h index 1cc925a2..56e903ed 100644 --- a/doric-iOS/Pod/Classes/DoricRegistry.h +++ b/doric-iOS/Pod/Classes/DoricRegistry.h @@ -26,11 +26,14 @@ NS_ASSUME_NONNULL_BEGIN @class DoricLibrary; +@class DoricJSEngine; @interface DoricRegistry : NSObject @property(nonatomic, strong) UIImage *defaultPlaceHolderImage; @property(nonatomic, strong) UIImage *defaultErrorImage; +- (instancetype)initWithJSEngine:(DoricJSEngine *)jsEngine; + - (NSString *)acquireJSBundle:(NSString *)name; - (void)registerJSBundle:(NSString *)bundle withName:(NSString *)name; @@ -46,8 +49,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)setEnvironment:(NSString *)key variable:(id)value; -- (NSDictionary *)environmentVariables; - - (void)registerMonitor:(id )monitor; + (void)register:(DoricLibrary *)library; diff --git a/doric-iOS/Pod/Classes/DoricRegistry.m b/doric-iOS/Pod/Classes/DoricRegistry.m index 45b9834a..a774c73c 100644 --- a/doric-iOS/Pod/Classes/DoricRegistry.m +++ b/doric-iOS/Pod/Classes/DoricRegistry.m @@ -48,12 +48,12 @@ #import "DoricLibrary.h" #import "DoricNotificationPlugin.h" #import "DoricStatusBarPlugin.h" -#import "DoricUtil.h" #import "DoricCoordinatorPlugin.h" #import "DoricSwitchNode.h" #import "DoricNotchPlugin.h" #import "DoricFlexNode.h" #import "DoricKeyboardPlugin.h" +#import "DoricJSEngine.h" @interface DoricLibraries : NSObject @property(nonatomic, strong) NSMutableSet *libraries; @@ -87,12 +87,19 @@ @interface DoricRegistry () @property(nonatomic, strong) NSMutableDictionary *bundles; @property(nonatomic, strong) NSMutableDictionary *plugins; @property(nonatomic, strong) NSMutableDictionary *nodes; -@property(nonatomic, strong) NSMutableDictionary *envVariables; @property(nonatomic, strong) NSMutableSet > *monitors; +@property(nonatomic, weak) DoricJSEngine *jsEngine; @end @implementation DoricRegistry +- (instancetype)initWithJSEngine:(DoricJSEngine *)jsEngine { + if (self = [super init]) { + _jsEngine = jsEngine; + } + return self; +} + + (void)register:(DoricLibrary *)library { [DoricLibraries.instance.libraries addObject:library]; for (NSValue *value in DoricLibraries.instance.registries) { @@ -108,7 +115,6 @@ - (instancetype)init { _bundles = [NSMutableDictionary new]; _plugins = [NSMutableDictionary new]; _nodes = [NSMutableDictionary new]; - _envVariables = [NSMutableDictionary new]; [self innerRegister]; _monitors = [NSMutableSet new]; [DoricLibraries.instance.libraries enumerateObjectsUsingBlock:^(DoricLibrary *obj, BOOL *stop) { @@ -180,11 +186,7 @@ - (Class)acquireViewNode:(NSString *)name { } - (void)setEnvironment:(NSString *)key variable:(id)value { - self.envVariables[key] = value; -} - -- (NSDictionary *)environmentVariables { - return self.envVariables; + [self.jsEngine setEnvironment:key variable:value]; } - (void)registerMonitor:(id )monitor { diff --git a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h index 5746cd9b..d7fbe41e 100644 --- a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h +++ b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.h @@ -50,6 +50,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)initJSEngine; - (void)teardown; + +- (void)setEnvironment:(NSString *)key variable:(id)value; @end NS_ASSUME_NONNULL_END diff --git a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m index 34325d98..62c52c75 100644 --- a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m +++ b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m @@ -27,6 +27,7 @@ #import "DoricBridgeExtension.h" #import #import "DoricContext.h" +#import "DoricContextManager.h" @interface DoricDefaultMonitor : NSObject @end @@ -47,12 +48,14 @@ @interface DoricJSEngine () @property(nonatomic, strong) NSMutableDictionary *environmentDictionary; @property(nonatomic, strong) NSThread *jsThread; @property(nonatomic, assign) BOOL destroyed; +@property(nonatomic, assign) BOOL initialized; @end @implementation DoricJSEngine - (instancetype)init { if (self = [super init]) { + _initialized = NO; _jsThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadRun) object:nil]; [_jsThread start]; NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; @@ -88,7 +91,7 @@ - (instancetype)init { @"localeLanguage": [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode], @"localeCountry": [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode], }.mutableCopy; - self.registry = [[DoricRegistry alloc] init]; + self.registry = [[DoricRegistry alloc] initWithJSEngine:self]; [self ensureRunOnJSThread:^() { self.timers = [[NSMutableDictionary alloc] init]; self.bridgeExtension = [DoricBridgeExtension new]; @@ -96,12 +99,25 @@ - (instancetype)init { [self initJSEngine]; [self initJSExecutor]; [self initDoricEnvironment]; + self.initialized = YES; }]; [self.registry registerMonitor:[DoricDefaultMonitor new]]; } return self; } +- (void)setEnvironment:(NSString *)key variable:(id)value { + [self ensureRunOnJSThread:^{ + self.environmentDictionary[key] = value; + if (self.initialized) { + [self.jsExecutor injectGlobalJSObject:INJECT_ENVIRONMENT obj:[self.environmentDictionary copy]]; + for (DoricContext *doricContext in DoricContextManager.instance.aliveContexts) { + [doricContext onEnvChanged]; + } + } + }]; +} + - (void)teardown { _destroyed = YES; //To ensure runloop continue. @@ -136,9 +152,6 @@ - (void)initJSEngine { - (void)initJSExecutor { __weak typeof(self) _self = self; - [self.registry.environmentVariables enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { - self.environmentDictionary[key] = obj; - }]; [self.jsExecutor injectGlobalJSObject:INJECT_ENVIRONMENT obj:[self.environmentDictionary copy]]; [self.jsExecutor injectGlobalJSObject:INJECT_LOG obj:^(NSString *type, NSString *message) { if ([type isEqualToString:@"e"]) { diff --git a/doric-iOS/Pod/Classes/Util/DoricConstant.h b/doric-iOS/Pod/Classes/Util/DoricConstant.h index c12f7df4..699edeb8 100644 --- a/doric-iOS/Pod/Classes/Util/DoricConstant.h +++ b/doric-iOS/Pod/Classes/Util/DoricConstant.h @@ -67,3 +67,5 @@ extern NSString *const DORIC_ENTITY_SHOW; extern NSString *const DORIC_ENTITY_HIDDEN; extern NSString *const DORIC_ENTITY_BUILD; + +extern NSString *const DORIC_ENTITY_ENV_CHANGE; diff --git a/doric-iOS/Pod/Classes/Util/DoricConstant.m b/doric-iOS/Pod/Classes/Util/DoricConstant.m index c47c4ad1..9a9f47e2 100644 --- a/doric-iOS/Pod/Classes/Util/DoricConstant.m +++ b/doric-iOS/Pod/Classes/Util/DoricConstant.m @@ -85,3 +85,5 @@ NSString *const DORIC_ENTITY_HIDDEN = @"__onHidden__"; NSString *const DORIC_ENTITY_BUILD = @"__build__"; + +NSString *const DORIC_ENTITY_ENV_CHANGE = @"__onEnvChanged__"; diff --git a/doric-js/src/ui/panel.ts b/doric-js/src/ui/panel.ts index 4d99e20a..29755f49 100644 --- a/doric-js/src/ui/panel.ts +++ b/doric-js/src/ui/panel.ts @@ -39,7 +39,10 @@ export abstract class Panel { onDestroy() { } onShow() { } onHidden() { } - + onEnvChanged() { + this.__root__.children.length = 0 + this.build(this.__root__) + } abstract build(rootView: Group): void private __data__?: object @@ -126,6 +129,11 @@ export abstract class Panel { this.build(this.__root__) } + @NativeCall + private __onEnvChanged__() { + this.onEnvChanged() + } + @NativeCall private __response__(viewIds: string[], callbackId: string) { const v = this.retrospectView(viewIds)