Skip to content

Commit

Permalink
Fix HarmonyOS Next platform interface for calling arkts using JavaScr…
Browse files Browse the repository at this point in the history
…ipt (#18062)

* Fix HarmonyOS Next platform interface for calling arkts using JavaScript

* Optimized interface implementation

* Improve annotations

* Improve the annotation.

---------

Co-authored-by: qiuguohua <[email protected]>
  • Loading branch information
qiuguohua and qiuguohua authored Dec 20, 2024
1 parent eb949c6 commit 40e0769
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 33 deletions.
2 changes: 2 additions & 0 deletions cocos/native-binding/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ if (NATIVE) {
globalJsb.__bridge = new globalThis.JavascriptJavaBridge();
} else if (globalThis.JavaScriptObjCBridge && (sys.os === sys.OS.IOS || sys.os === sys.OS.OSX)) {
globalJsb.__bridge = new globalThis.JavaScriptObjCBridge();
} else if (globalThis.JavaScriptArkTsBridge && (sys.os === sys.OS.OPENHARMONY)) {
globalJsb.__bridge = new globalThis.JavaScriptArkTsBridge();
} else {
globalJsb.__bridge = null;
}
Expand Down
29 changes: 25 additions & 4 deletions cocos/native-binding/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1262,10 +1262,31 @@ export declare namespace native {
* @en call Objective-C/Java static methods
* @zh 调用 Objective-C/Java 静态方法
*
* @param className : @en the class name of the Objective-C/Java class @zh Objective-C/Java 类的类名
* @param methodName : @en the method name of the Objective-C/Java class @zh Objective-C/Java 类的方法名
* @param methodSignature : @en the method signature of the Objective-C/Java class @zh Objective-C/Java 方法签名
* @param parameters : @en the parameters of the Objective-C/Java class to translate @zh 传递至该 Objective-C/Java 方法的参数
* @param className : @en the class name of the Objective-C/Java/ArkTs class @zh Objective-C/Java/ArkTs 类的类名
* @param methodName : @en the method name of the Objective-C/Java/ArkT class @zh Objective-C/Java/ArkT 类的方法名
* @param methodSignature :
* @en
* - On the Android platform: Represents the method signature of the Java class.
* - On the Mac/iOS platform: Represents the first parameter of the Objective-C method.
* - On the HarmonyOS Next platform: Represents all parameters of the ArkTs method.
* If multiple parameters are required, can be converted into a JSON string.
* @zh
* - 在 Android 平台:表示 Java 方法的签名。
* - 在 Mac 或 iOS 平台:表示 Objective-C 方法的第一个参数。
* - 在 HarmonyOS Next 平台:表示 ArkTs 方法的所有参数。如果需要传入多个参数,可以将它们转换为 JSON 字符串。
*
* @param parameters :
* @en
* - On the Android platform: Represents the parameters passed to the Java method.
* - On the Mac/iOS platform: Represents the second or subsequent parameters of the Objective-C method.
* - On the HarmonyOS Next platform: Indicates whether the ArkTs method is synchronous or asynchronous.
* The default is `true`, meaning the ArkTs method is called synchronously.
* Note that calling asynchronous ArkTs methods may block while waiting for results.
* @zh
* - 在 Android 平台:传递到 Java 方法的参数。
* - 在 Mac 或 iOS 平台:传递到 Objective-C 方法的第二个或更多参数。
* - 在 HarmonyOS Next 平台:表示调用 ArkTs 方法是同步还是异步。
* 默认值为 `true`,表示调用ArkTs的同步方法。注意,调用异步方法可能会阻塞以等待结果。
*/
export function callStaticMethod(className: string, methodName: string, methodSignature: string, ...parameters: any): any;
}
Expand Down
40 changes: 20 additions & 20 deletions native/cocos/bindings/jswrapper/jsvm/CommonHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,26 @@
} while (0)

// Returns nullptr if the_call doesn't return JSVM_OK.
#define NODE_API_CALL(status, env, the_call) \
status = the_call; \
if (status != JSVM_OK) { \
bool isPending = false; \
if (JSVM_OK == OH_JSVM_IsExceptionPending((env), &isPending) && isPending) { \
JSVM_Value error; \
if (JSVM_OK == OH_JSVM_GetAndClearLastException((env), &error)) { \
JSVM_Value stack; \
OH_JSVM_GetNamedProperty((env), error, "stack", &stack); \
JSVM_Value message; \
OH_JSVM_GetNamedProperty((env), error, "message", &message); \
char stackstr[256]; \
OH_JSVM_GetValueStringUtf8(env, stack, stackstr, 256, nullptr); \
SE_LOGE("JSVM error stack: %{public}s", stackstr); \
char messagestr[256]; \
OH_JSVM_GetValueStringUtf8(env, message, messagestr, 256, nullptr); \
SE_LOGE("JSVM error message: %{public}s", messagestr); \
} \
} \
} \
#define NODE_API_CALL(status, env, the_call) \
status = the_call; \
if (status != JSVM_OK) { \
bool isPending = false; \
if (JSVM_OK == OH_JSVM_IsExceptionPending((env), &isPending) && isPending) { \
JSVM_Value error; \
if (JSVM_OK == OH_JSVM_GetAndClearLastException((env), &error)) { \
JSVM_Value stack; \
OH_JSVM_GetNamedProperty((env), error, "stack", &stack); \
JSVM_Value message; \
OH_JSVM_GetNamedProperty((env), error, "message", &message); \
char stackstr[256]; \
OH_JSVM_GetValueStringUtf8(env, stack, stackstr, 256, nullptr); \
SE_LOGE("JSVM error stack: %s", stackstr); \
char messagestr[256]; \
OH_JSVM_GetValueStringUtf8(env, message, messagestr, 256, nullptr); \
SE_LOGE("JSVM error message: %s", messagestr); \
} \
} \
} \
NODE_API_CALL_BASE(env, status, nullptr)

// Returns empty if the_call doesn't return JSVM_OK.
Expand Down
21 changes: 12 additions & 9 deletions native/cocos/bindings/manual/JavaScriptArkTsBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,24 +203,27 @@ static bool JavaScriptArkTsBridge_callStaticMethod(se::State& s) {
const auto& args = s.args();
int argc = (int)args.size();

if (argc == 4) {
if (argc == 3 || argc == 4) {
bool ok = false;
bool isSyn;
bool isSync = true;
std::string clsPath, methodName, paramStr;

isSyn = seval_to_type<bool>(args[0], ok);
SE_PRECONDITION2(ok, false, "Converting isSyn failed!");

clsPath = seval_to_type<std::string>(args[1], ok);
clsPath = seval_to_type<std::string>(args[0], ok);
SE_PRECONDITION2(ok, false, "Converting clsPath failed!");

methodName = seval_to_type<std::string>(args[2], ok);
methodName = seval_to_type<std::string>(args[1], ok);
SE_PRECONDITION2(ok, false, "Converting methodName failed!");

paramStr = seval_to_type<std::string>(args[3], ok);
paramStr = seval_to_type<std::string>(args[2], ok);
SE_PRECONDITION2(ok, false, "Converting paramStr failed!");

if(argc == 4) {
ok = args[3].isBoolean();
SE_PRECONDITION2(ok, false, "isSync must be boolean type");
isSync = args[3].toBoolean();
}

JavaScriptArkTsBridge::CallInfo call(isSyn, clsPath.c_str(), methodName.c_str(), paramStr.c_str());
JavaScriptArkTsBridge::CallInfo call(isSync, clsPath.c_str(), methodName.c_str(), paramStr.c_str());
ok = call.execute(s.rval());
if (!ok) {
s.rval().setUndefined();
Expand Down

0 comments on commit 40e0769

Please sign in to comment.