在 Delphi 中实施 Java/Android 的 callback/listeners
Implementing Java/Android's callback/listeners in Delphi
我正在尝试在 Delphi 10.2 Tokyo 中创建一个 Android 应用程序,它使用了 Camera2 API. I used Java2OP to create the interfaces that I need. Some of these interfaces are for callback/listeners. For example CameraDevice.StateCallback,Java2OP 已将其转换为:
JCameraDevice_StateCallbackClass = interface(JObjectClass)
['{3F5A7394-FD15-439C-9BFB-DF8D43F9F930}']
{class} function _GetERROR_CAMERA_DEVICE: Integer; cdecl;
{class} function _GetERROR_CAMERA_DISABLED: Integer; cdecl;
{class} function _GetERROR_CAMERA_IN_USE: Integer; cdecl;
{class} function _GetERROR_CAMERA_SERVICE: Integer; cdecl;
{class} function _GetERROR_MAX_CAMERAS_IN_USE: Integer; cdecl;
{class} function init: JCameraDevice_StateCallback; cdecl;
{class} property ERROR_CAMERA_DEVICE: Integer read _GetERROR_CAMERA_DEVICE;
{class} property ERROR_CAMERA_DISABLED: Integer read _GetERROR_CAMERA_DISABLED;
{class} property ERROR_CAMERA_IN_USE: Integer read _GetERROR_CAMERA_IN_USE;
{class} property ERROR_CAMERA_SERVICE: Integer read _GetERROR_CAMERA_SERVICE;
{class} property ERROR_MAX_CAMERAS_IN_USE: Integer read _GetERROR_MAX_CAMERAS_IN_USE;
end;
[JavaSignature('android/hardware/camera2/CameraDevice$StateCallback')]
JCameraDevice_StateCallback = interface(JObject)
['{3A3944F5-A71F-4CD6-98C6-04B8D65C3B52}']
procedure onClosed(camera: JCameraDevice); cdecl;//Deprecated
procedure onDisconnected(camera: JCameraDevice); cdecl;//Deprecated
procedure onError(camera: JCameraDevice; error: Integer); cdecl;//Deprecated
procedure onOpened(camera: JCameraDevice); cdecl;//Deprecated
end;
TJCameraDevice_StateCallback = class(TJavaGenericImport<JCameraDevice_StateCallbackClass, JCameraDevice_StateCallback>) end;
据我了解,我应该将 TJavaLocal
与我想用作 callback/listener 的接口结合使用(在本例中为 JCameraDevice_StateCallbackClass
)。这是我所做的:
单位 CamDevStateCallback;
interface
uses
Androidapi.JNIBridge, android.hardware.camera2;
type
TCamera2Event = procedure(camera: JCameraDevice) of object;
TCamera2ErrorEvent = procedure(camera: JCameraDevice; error: Integer) of object;
TCamDevStateCallback = class(TJavaLocal, JCameraDevice_StateCallback)
protected
FOnClosed: TCamera2Event;
FOnDisconnected: TCamera2Event;
FOnError: TCamera2ErrorEvent;
FOnOpen: TCamera2Event;
public
procedure onClosed(camera: JCameraDevice); cdecl;
procedure onDisconnected(camera: JCameraDevice); cdecl;
procedure onError(camera: JCameraDevice; error: Integer); cdecl;
procedure onOpened(camera: JCameraDevice); cdecl;
class function CreateNew(aOnOpen, aOnClosed, aOnDisconnected: TCamera2Event; aOnError: TCamera2ErrorEvent): JCameraDevice_StateCallback;
property OnCameraClosed: TCamera2Event read FOnClosed write FOnClosed;
property OnCameraDisconnected: TCamera2Event read FOnDisconnected write FOnDisconnected;
property OnCameraError: TCamera2ErrorEvent read FOnError write FOnError;
property OnCameraOpen: TCamera2Event read FOnOpen write FOnOpen;
end;
implementation
{ TCamDevStateCallback }
class function TCamDevStateCallback.CreateNew(aOnOpen, aOnClosed, aOnDisconnected: TCamera2Event;
aOnError: TCamera2ErrorEvent): JCameraDevice_StateCallback;
var
tmpObj: TCamDevStateCallback;
begin
tmpObj := TCamDevStateCallback.Create;
tmpObj.OnCameraClosed := aOnClosed;
tmpObj.OnCameraDisconnected := aOnDisconnected;
tmpObj.OnCameraError := aOnError;
tmpObj.OnCameraOpen := aOnOpen;
Result := TJCameraDevice_StateCallback.Wrap((tmpObj as ILocalObject).GetObjectID);
end;
procedure TCamDevStateCallback.onClosed(camera: JCameraDevice);
begin
if Assigned(FOnClosed) then
FOnClosed(camera);
end;
procedure TCamDevStateCallback.onDisconnected(camera: JCameraDevice);
begin
if Assigned(FOnDisconnected) then
FOnDisconnected(camera);
end;
procedure TCamDevStateCallback.onError(camera: JCameraDevice; error: Integer);
begin
if Assigned(FOnError) then
FOnError(camera, error);
end;
procedure TCamDevStateCallback.onOpened(camera: JCameraDevice);
begin
if Assigned(FOnOpen) then
FOnOpen(camera);
end;
end.
此代码无法编译,因为它抱怨 equals
、toString
与之前的声明不同,并且 getClass
、notify
、notifyAll
和 wait
不见了。
android.hardware.camera2.pas由Java2OP创建,包含[=23=的接口定义] 等等。
正如@DaveNottage 所指出的,这里的潜在问题是 CameraDevice.StateCallback
不是 Java 侦听器接口,而是 Java 回调 class(尽管是abstract class 因此在某些方面类似于接口,但不是接口)。
因为它不是 Java 接口,所以它 不是 使用 TJavaLocal
实现的候选接口,尽管在 Delphi 中它由接口 表示(因为所有 Java 接口和 class 都是)。
TJavaLocal
用于实现 Java 接口,通常是侦听器接口。它不提供从 Java class(甚至是抽象 Java class)继承的方法。
线索是Java2OP创建的重要接口继承自JObject
表明它是Java基于Object
的一部分class 层次结构。导入时的侦听器接口继承自 IJavaInstance
.
Delphi 不支持从 Android Java classes 继承(与其 iOS 支持相比,其中 Delphi 是否支持从 Objective-C classes 继承,这要归功于 Objective-C 是一个本地系统,不像 Android 的托管 Java虚拟机系统)
我正在尝试在 Delphi 10.2 Tokyo 中创建一个 Android 应用程序,它使用了 Camera2 API. I used Java2OP to create the interfaces that I need. Some of these interfaces are for callback/listeners. For example CameraDevice.StateCallback,Java2OP 已将其转换为:
JCameraDevice_StateCallbackClass = interface(JObjectClass)
['{3F5A7394-FD15-439C-9BFB-DF8D43F9F930}']
{class} function _GetERROR_CAMERA_DEVICE: Integer; cdecl;
{class} function _GetERROR_CAMERA_DISABLED: Integer; cdecl;
{class} function _GetERROR_CAMERA_IN_USE: Integer; cdecl;
{class} function _GetERROR_CAMERA_SERVICE: Integer; cdecl;
{class} function _GetERROR_MAX_CAMERAS_IN_USE: Integer; cdecl;
{class} function init: JCameraDevice_StateCallback; cdecl;
{class} property ERROR_CAMERA_DEVICE: Integer read _GetERROR_CAMERA_DEVICE;
{class} property ERROR_CAMERA_DISABLED: Integer read _GetERROR_CAMERA_DISABLED;
{class} property ERROR_CAMERA_IN_USE: Integer read _GetERROR_CAMERA_IN_USE;
{class} property ERROR_CAMERA_SERVICE: Integer read _GetERROR_CAMERA_SERVICE;
{class} property ERROR_MAX_CAMERAS_IN_USE: Integer read _GetERROR_MAX_CAMERAS_IN_USE;
end;
[JavaSignature('android/hardware/camera2/CameraDevice$StateCallback')]
JCameraDevice_StateCallback = interface(JObject)
['{3A3944F5-A71F-4CD6-98C6-04B8D65C3B52}']
procedure onClosed(camera: JCameraDevice); cdecl;//Deprecated
procedure onDisconnected(camera: JCameraDevice); cdecl;//Deprecated
procedure onError(camera: JCameraDevice; error: Integer); cdecl;//Deprecated
procedure onOpened(camera: JCameraDevice); cdecl;//Deprecated
end;
TJCameraDevice_StateCallback = class(TJavaGenericImport<JCameraDevice_StateCallbackClass, JCameraDevice_StateCallback>) end;
据我了解,我应该将 TJavaLocal
与我想用作 callback/listener 的接口结合使用(在本例中为 JCameraDevice_StateCallbackClass
)。这是我所做的:
单位 CamDevStateCallback;
interface
uses
Androidapi.JNIBridge, android.hardware.camera2;
type
TCamera2Event = procedure(camera: JCameraDevice) of object;
TCamera2ErrorEvent = procedure(camera: JCameraDevice; error: Integer) of object;
TCamDevStateCallback = class(TJavaLocal, JCameraDevice_StateCallback)
protected
FOnClosed: TCamera2Event;
FOnDisconnected: TCamera2Event;
FOnError: TCamera2ErrorEvent;
FOnOpen: TCamera2Event;
public
procedure onClosed(camera: JCameraDevice); cdecl;
procedure onDisconnected(camera: JCameraDevice); cdecl;
procedure onError(camera: JCameraDevice; error: Integer); cdecl;
procedure onOpened(camera: JCameraDevice); cdecl;
class function CreateNew(aOnOpen, aOnClosed, aOnDisconnected: TCamera2Event; aOnError: TCamera2ErrorEvent): JCameraDevice_StateCallback;
property OnCameraClosed: TCamera2Event read FOnClosed write FOnClosed;
property OnCameraDisconnected: TCamera2Event read FOnDisconnected write FOnDisconnected;
property OnCameraError: TCamera2ErrorEvent read FOnError write FOnError;
property OnCameraOpen: TCamera2Event read FOnOpen write FOnOpen;
end;
implementation
{ TCamDevStateCallback }
class function TCamDevStateCallback.CreateNew(aOnOpen, aOnClosed, aOnDisconnected: TCamera2Event;
aOnError: TCamera2ErrorEvent): JCameraDevice_StateCallback;
var
tmpObj: TCamDevStateCallback;
begin
tmpObj := TCamDevStateCallback.Create;
tmpObj.OnCameraClosed := aOnClosed;
tmpObj.OnCameraDisconnected := aOnDisconnected;
tmpObj.OnCameraError := aOnError;
tmpObj.OnCameraOpen := aOnOpen;
Result := TJCameraDevice_StateCallback.Wrap((tmpObj as ILocalObject).GetObjectID);
end;
procedure TCamDevStateCallback.onClosed(camera: JCameraDevice);
begin
if Assigned(FOnClosed) then
FOnClosed(camera);
end;
procedure TCamDevStateCallback.onDisconnected(camera: JCameraDevice);
begin
if Assigned(FOnDisconnected) then
FOnDisconnected(camera);
end;
procedure TCamDevStateCallback.onError(camera: JCameraDevice; error: Integer);
begin
if Assigned(FOnError) then
FOnError(camera, error);
end;
procedure TCamDevStateCallback.onOpened(camera: JCameraDevice);
begin
if Assigned(FOnOpen) then
FOnOpen(camera);
end;
end.
此代码无法编译,因为它抱怨 equals
、toString
与之前的声明不同,并且 getClass
、notify
、notifyAll
和 wait
不见了。
android.hardware.camera2.pas由Java2OP创建,包含[=23=的接口定义] 等等。
正如@DaveNottage 所指出的,这里的潜在问题是 CameraDevice.StateCallback
不是 Java 侦听器接口,而是 Java 回调 class(尽管是abstract class 因此在某些方面类似于接口,但不是接口)。
因为它不是 Java 接口,所以它 不是 使用 TJavaLocal
实现的候选接口,尽管在 Delphi 中它由接口 表示(因为所有 Java 接口和 class 都是)。
TJavaLocal
用于实现 Java 接口,通常是侦听器接口。它不提供从 Java class(甚至是抽象 Java class)继承的方法。
线索是Java2OP创建的重要接口继承自JObject
表明它是Java基于Object
的一部分class 层次结构。导入时的侦听器接口继承自 IJavaInstance
.
Delphi 不支持从 Android Java classes 继承(与其 iOS 支持相比,其中 Delphi 是否支持从 Objective-C classes 继承,这要归功于 Objective-C 是一个本地系统,不像 Android 的托管 Java虚拟机系统)