在Delphi XE7中,在Android设备上打开表单第二次时出现访问冲突问题。

3

当我第一次打开表单时,没有违规情况,但是当我首先选择一个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并关闭窗体时出现,我认为它与虚拟键盘有关,但我不确定。我没有使用虚拟键盘本身的任何方法。


1
尝试完全删除FormClose。您正在释放窗体两次。 - Dalija Prasnikar
2
@DalijaPrasnikar,这是一种情况,在此情况下不应使用 DisposeOf()。请参阅Android上的ShowModal了解详情。 - LU RD
@LURD 我也找到了在Android上使用showModal的教程,但在这种情况下它是不正确的。 - Remi
你所观察到的任何问题都可以算作是“意外行为”吗?这与文档中在移动平台上使用ShowModal时的警告有关,因为模态对话框不受支持。 - Rob Kennedy
@RobKennedy 好吧,因为我在 form.show 上遇到了同样的问题,所以不是这个原因。 - Remi
显示剩余2条评论
3个回答

4

更新

虽然我在这里的建议都是有文献资料支持的,但是在 Android 和多个表单方面仍然存在问题。请参见本帖后面的内容。


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

释放模态对话框的文档已经改变:使用 FireMonkey 模态对话框

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;

输入图像描述


更新

原始问题提出者已尝试了该解决方案,但其并不按预期工作。

调查后发现,有报告称其在移动 Android 平台上无法正常工作:

RSP-9692 在 Android 中运行时创建窗体

RSP-9665 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 中标记为已解决。这显然是不正确的。


我也尝试过这种方法,但仍然出现了错误。所以我猜@DalijaPrasnikar的方法是正确的。 - Remi
你确定已经移除了DisposeOf()调用吗?它根本不应该存在。 - LU RD
是的,我已经将它删除了。奇怪的是,我在其他表单上没有遇到这个问题。 - Remi
不要忘记将模态对话框的 OnClose 事件设置为 FormClose - LU RD
1
那个关于TEdit的链接对我来说似乎是个问题。感谢提供链接!看起来在XE7中没有解决。 - Remi
显示剩余2条评论

0

这个问题似乎只发生在 Delphi XE7 中。我现在使用的是 Delphi XE8,不再有这个问题了。


0

Embarcadero 文档 关于 FMX ShowModal 和移动平台的说明如下:

注意:Android 应用程序不支持模态对话框。您应该调用 Show 而不是调用 ShowModal,并让表单返回并调用您的事件。我们建议您在移动平台(iOS 和 Android)上都不使用模态对话框,因为可能会导致意外行为。不使用模态对话框可以消除调试和支持移动应用程序时可能出现的问题。


1
ShowModal 在内部调用 Show。因此,在 buttonclick 方法中没有任何阻塞。在 ShowModal 调用之后的任何代码都将在匿名方法之前执行。 - LU RD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接