我试图使用Delphi的JKeyCharacterMap.getEvents
函数从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函数返回的元素?
更新
我使用断点进行调试,其中引发了异常并且App在此函数Androidapi.JNIBridge.TJNIResolver.GetObjectArrayElement
上失败,因为JNIEnvRes
变量为nil
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;
但我不知道造成这种行为的原因。
答案 0 :(得分:1)
在我的测试中,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
为FClassID
,因此失败的对象是nil
。需要FClassID
来创建具有适当类的包装器对象。
WrapJNIReturn(AObject, FClassID, FBaseType.Handle, Result);
您有两种方法可以解决这个问题:
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;
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;