在 Delphi XE7 中的 Android 上第二次打开表单时发生访问冲突

Access violation when opening form 2th time on Android in Delphi XE7

当我第一次打开我的表单时,我没有遇到违规,但是当我首先 select 一个 TEdit 字段然后关闭表单,然后重新创建表单并打开它时,我遇到了违规。

创建表单的代码:

procedure TfrmNocoreDKS.actConfigExecute(Sender: TObject);
var
  confForm: TConfiguratie;
begin
  confForm := TConfiguratie.Create(nil);
  confForm.ShowModal(
    procedure(ModalResult: TModalResult)
    begin
      confForm.DisposeOf;//Also tried confForm.Free;
    end);
end;

我也试过这个来创建表单:

procedure TfrmNocoreDKS.actConfigExecute(Sender: TObject);
var
  confForm: TConfiguratie;
begin
  confForm := TConfiguratie.Create(nil);
  try
    confForm.ShowModal(
      procedure(ModalResult: TModalResult)
      begin
      end);
  finally
    confForm.free;
  end;
end;

关闭表单代码:

procedure TConfiguratie.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.caFree;
end;

因为违规仅在您单击任何 TEdit 然后关闭表单时出现,我认为这与虚拟键盘有关,但我不确定。我没有任何使用虚拟键盘本身的方法。

更新

虽然我在这里的建议已记录在案,但 Android 和多种形式仍然存在问题。见下文post。


根本不要调用 DisposeOf()FreeFormClose()caFree 调用是使其工作的关键。

如何处理模态对话框的文档已更改:Using FireMonkey Modal Dialog Boxes

FireMonkey 架构师现在已经为此努力了好几个版本,终于成功了

文档中的示例如何创建模态对话框:

procedure MyCurrentForm.MyButtonClick(Sender: TObject);
var
  dlg: TMyModalForm;
begin
  // Create an instance of a form.
  dlg := TMyModalForm.Create(nil);

  // Configure the form. For example, give it a display name.
  dlg.Caption := 'My Modal Dialog Box';

  // Show your dialog box and provide an anonymous method that handles the closing of your dialog box.
  dlg.ShowModal(
    procedure(ModalResult: TModalResult)
    begin
      // Do something.
    end
  );
end;

并释放模态对话框:

procedure TMyModalForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := TCloseAction.caFree;
end;


更新

OP 已尝试此解决方案,但未按预期工作。

调查 QC,有报告称这在移动 android 平台上无法正常工作:

RSP-9692 Runtime creation of forms in Android

RSP-9665 Access Violation in FMX.Platform.Android SendCMGestureMessage.

(您必须登录才能访问它们)。

后者解释了正在发生的事情。当模态窗体被销毁时,FFocusedControl 可能指向一个被销毁的控件。当 ARC 试图释放 FFocusedControl 时,这将导致分段错误。 FFocusedControl 必须声明为 [weak]。有关详细信息,请参阅 RSP-9665。

还有 QC-126524 [Android] Open/Close/Free sub form multiple times may cause crash on Android Platform when removing Focus from TEdit 报告了同样的事情,并已在 XE7 中解决。这显然不是真的。

Embarcadero documentation 关于 FMX ShowModal 和移动平台说

注意:Android 应用不支持模态对话框。您不应调用 ShowModal,而应调用 Show,并采用 return 形式并调用您的事件。我们建议您不要在任一移动平台(iOS 和 Android)上使用模态对话框,因为这可能会导致意外行为。不使用模态对话框可以消除调试和支持您的移动应用程序的潜在问题。

这个问题似乎只出现在 Delphi XE7 中。我现在正在使用 Delphi XE8,不再有这个问题了。