gpt4 book ai didi

android - 如何从 Delphi 访问 KeyCharacterMap.getEvents 函数返回的元素?

转载 作者:太空宇宙 更新时间:2023-11-03 10:39:01 24 4
gpt4 key购买 nike

我正在尝试使用 JKeyCharacterMap.getEvents来自 Delphi 的函数从 Char 中获取 KeyCode。

所以我正在使用这段代码。

uses
FMX.Platform.Android,
Androidapi.Helpers,
Androidapi.JNIBridge;

var
s : string;
PlatformKey : Word;
FKeyCharacterMap: JKeyCharacterMap;
events : TJavaObjectArray<JKeyEvent>;
event : JKeyEvent;
chars: TJavaArray<Char>;
l : integer;
begin
FKeyCharacterMap := TJKeyCharacterMap.JavaClass.load(TJKeyCharacterMap.JavaClass.BUILT_IN_KEYBOARD);

chars := TJavaArray<Char>.Create(1);
chars[0] := 'A';
events := FKeyCharacterMap.getEvents(chars);

l := events.Length; //this returns 4
if l>0 then
begin
event := events[0]; // Segmentation fault (11)
PlatformKey := event.getKeyCode;
end;

end;

但不幸的是,一旦我尝试访问 JKeyCharacterMap.getEvents 返回的数组的某些元素,函数我得到一个Segmentation fault (11)异常。

所以问题是,如何从 Delphi 访问 KeyCharacterMap.getEvents 函数返回的元素?

更新

我使用断点进行调试,在该断点处引发了异常,应用在此函数上失败 Androidapi.JNIBridge.TJNIResolver.GetObjectArrayElement因为JNIEnvRes变量为零

class function TJNIResolver.GetObjectArrayElement(AArray: JNIObjectArray; Index: JNISize): JNIObject;
begin
GetJNIEnv;
//JNIEnvRes is nil
Result := JNIEnvRes^.GetObjectArrayElement(JNIEnvRes, AArray, Index);
end;

GetJNIEnv函数无法为 JNIEnvRes 赋值变量。

class function TJNIResolver.GetJNIEnv: PJNIEnv;
begin
if JNIEnvRes = nil then
PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @JNIEnvRes, nil);
Result := JNIEnvRes;
end;

但我不知道是什么导致了这种行为。

最佳答案

在我的测试中,GetJNIEnv 运行良好。虽然它似乎返回 nil,但它是 Delphi 的调试器显示了错误的 JNIEnvRes 值,正如您所看到的 Result 不是 nil:

class function TJNIResolver.GetJNIEnv: PJNIEnv;
begin
if JNIEnvRes = nil then
PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @JNIEnvRes, nil);
Result := JNIEnvRes;
// debugger shows JNIEnvRes as nil and Result as not nil
end;

事实上,GetObjectArrayElement 正在返回预期的对象,但随后的 WrapJNIReturn 失败了,因为 FClassIDFClassID 是创建具有适当类的包装器对象所必需的。

WrapJNIReturn(AObject, FClassID, FBaseType.Handle, Result);

解决这个问题有两种方法:

1。获取原始项目并将其包装在具有正确类型的对象中

events := FKeyCharacterMap.getEvents(chars);

l := events.Length; //this returns 4
if l>0 then
begin
//event := events[0]; // Fails!
event := TJKeyEvent.Wrap(events.GetRawItem(0)); // works
PlatformKey := event.getKeyCode;
end;

2。使用正确的 ClassID 将数组包装在一个数组中

events := TJavaObjectArray<JKeyEvent>.Wrap(FKeyCharacterMap.getEvents(chars));

l := events.Length; //this returns 4
if l>0 then
begin
event := events[0]; // now working well
PlatformKey := event.getKeyCode;
end;

关于android - 如何从 Delphi 访问 KeyCharacterMap.getEvents 函数返回的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37902755/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com