用反射机制实现二次开发
LayaNative通过提供反射机制来帮助开发者可以方便的进行二次开发, 下面通过示例来了解一下如何进行二次开发。
HarmonyOS、Linux和Window平台不支持反射机制,后续建议优先使用原生平台通信实现二次开发
1. 调用静态函数
Section titled “1. 调用静态函数”使用LayaNative, 可以在JavaScript层调用移动端的原生开发语言(Android下Java, iOS下Objective-C)编写的静态函数。
1.1 JavaScript层
Section titled “1.1 JavaScript层”JavaScript层的调用方式:在构建发布前,使用LayaAir-IDE在脚本中添加如下代码,发布后会将TS编译为JS:
var os = conchConfig.getOS(); var bridge; var obj = {} as any; if (os == "Conch-ios") { bridge = PlatformClass.createClass("JSBridge");//创建脚步代理 } else if (os == "Conch-android") { //需要完整的类路径,注意与iOS的不同 bridge = PlatformClass.createClass("demo.JSBridge");//创建脚步代理 }
if (os == "Conch-ios") { //iOS注意函数签名,注意与Android的不同 alert(bridge.call("testString:","hello")); alert(bridge.call("testNumber:",256.0)); alert(bridge.call("testBool:",false)); obj.value = "Hello OC!"; bridge.callWithBack(function(value: any) { var obj = JSON.parse(value) alert(obj.value); },"testAsyncCallback:", JSON.stringify(obj)); } else if (os == "Conch-android") { alert(bridge.call("testString","hello")); alert(bridge.call("testNumber",256.0)); alert(bridge.call("testBool",false)); obj.value = "Hello Java!"; bridge.callWithBack(function(value: any) { var obj = JSON.parse(value) alert(obj.value); },"testAsyncCallback",JSON.stringify(obj)); }添加上述代码时,如果某些native中的方法没有定义,可以这样写:
(window as any).xxxx,例如,(window as any).conchConfig.getOS()。
1.2 Android/Java层
Section titled “1.2 Android/Java层”发布后,使用Android Studio打开项目,在类JSBridge中添加下列函数:
public static String testString(String value) { Log.d("JSBridge", "java: " + value); return "LayaBox"; } public static double testNumber(double value) { Log.d("JSBridge", "java: " + value); return 512; } public static boolean testBool(boolean value) { Log.d("JSBridge", "java: " + value); return value ? false : true; } public static void testAsyncCallback(String json) { //js thread try { JSONObject root = new JSONObject(json); Log.d("JSBridge", "java: " + root.getString( "value" )); } catch (JSONException e) { e.printStackTrace(); } m_Handler.post( new Runnable() { public void run() { //ui thread update ui JSONObject obj = new JSONObject(); try { obj.put("value", "Hello JS!"); } catch (JSONException e) { e.printStackTrace(); } ExportJavaFunction.CallBackToJS(JSBridge.class,"testAsyncCallback", obj.toString()); } }); }1.3 iOS/OC层
Section titled “1.3 iOS/OC层”发布后,使用XCode打开项目,在类JSBridge中添加下列函数:
+(NSString*)testString:(NSString*)value { NSLog(@"OC: %@",value); return @"LayaBox"; } +(NSNumber*)testNumber:(NSNumber*)value { NSLog(@"OC: %@",value); return @512; } +(NSNumber*)testBool:(NSNumber*)value { NSLog(@"OC: %d",value.boolValue); return [NSNumber numberWithBool:value.boolValue ? NO : YES]; } +(void)testAsyncCallback:(NSString*)json { //js thread NSError* error = nil; NSData* jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary* dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; NSLog(@"OC: %@", [dict objectForKey:@"value"]); dispatch_async(dispatch_get_main_queue(), ^{ //ui thread NSError* error = nil; NSDictionary* dic = [NSDictionary dictionaryWithObject:@"Hello JS!" forKey:@"value"]; NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error]; NSString* jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; [[conchRuntime GetIOSConchRuntime] callbackToJSWithClass:self.class methodName:@"testAsyncCallback:" ret:jsonStr]; }); }注意:
(1)函数参数只支持布尔、浮点、字符串等基本类型,支持返回值。原生函数运行在脚本线程,更新UI需要转到UI线程,支持异步回调函数。
(2)OC源文件后缀要改成.mm,OC的方法是静态的类方法要用+。
2. 平台代码(Android/iOS)主动执行js脚本
Section titled “2. 平台代码(Android/iOS)主动执行js脚本”iOS/OC执行JS脚本:
[[conchRuntime GetIOSConchRuntime] runJS:@"alert('hello')"];Android/Java执行JS脚本:
ConchJNI.RunJS("alert('hello world')");