简体   繁体   English

在Delphi XE7中在Android上第2次打开表单时访问冲突

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

When I open my form for the first time I get no violation, but when I first select a TEdit field and then close the form and then recreate the form and open it I get the Violation. 当我第一次打开我的表单时,我没有违规,但是当我第一次选择TEdit字段然后关闭表单然后重新创建表单并打开它时,我得到违规。

Code for creating the form: 创建表单的代码:

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;

I've also tried this for creating the form: 我也试过这个来创建表单:

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;

Code for Closing the form: 关闭表格的代码:

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

Because the violation only appears when you click on any TEdit and then close the form I think it has something to do with the virtual keyboard, but i'm not sure. 因为违规只出现在你点击任何TEdit然后关闭表格时我认为它与虚拟键盘有关,但我不确定。 I don't have any methods that use the virtual keyboard itself. 我没有任何使用虚拟键盘本身的方法。

Update 更新

While my suggestions here are as documented, there are still problems with Android and multiple forms. 虽然我的建议在此处有记录,但Android和多种形式仍存在问题。 See later in this post. 请参阅本文后面的内容。


Do not call DisposeOf() or Free at all. 不要调用DisposeOf()Free The FormClose() and the caFree call is the key to make it work. FormClose()caFree调用是使其工作的关键。

The documentation how to dispose of a modal dialog has been changed: Using FireMonkey Modal Dialog Boxes . 有关如何处理模式对话框的文档已更改: 使用FireMonkey模式对话框

The FireMonkey architects has struggled with this for several versions now, and finally it works . FireMonkey架构师现在已经在几个版本中努力解决这个问题, 最后它的工作原理

Example from doc how to create a modal dialog: doc中如何创建模式对话框的示例:

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;

And to free your modal dialog: 并释放你的模态对话框:

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

在此输入图像描述


Update 更新

The OP has tried this solution and it does not work as expected. OP已尝试此解决方案,但无法按预期工作。

Looking into QC, there are reports claiming that this does not work as expected on mobile android platforms: 在调查QC时,有报道声称这在移动Android平台上无法正常工作:

RSP-9692 Runtime creation of forms in Android and RSP-9692在AndroidAndroid中运行时创建表单

RSP-9665 Access Violation in FMX.Platform.Android SendCMGestureMessage . FMX.Platform.Android SendCMGestureMessage中的RSP-9665访问冲突

(You must login to access them). (您必须登录才能访问它们)。

The latter explains what is happening. 后者解释了正在发生的事情。 When the modal form is destroyed, it is possible that FFocusedControl points to a destroyed control. 当模态形式被破坏时,FFocusedControl可能指向被破坏的控件。 When ARC is trying to release FFocusedControl this will cause a segmentation fault. 当ARC尝试释放FFocusedControl时,这将导致分段错误。 FFocusedControl must be declared [weak]. 必须声明FFocusedControl [弱]。 See the RSP-9665 for more details. 有关详细信息,请参阅RSP-9665。

There is also QC-126524 [Android] Open/Close/Free sub form multiple times may cause crash on Android Platform when removing Focus from TEdit reporting the same thing and closed as resolved in XE7. 还有QC-126524 [Android]开启/关闭/免费子表单多次可能会导致Android平台崩溃,从TEdit中删除Focus报告相同的事情并关闭在XE7中已解决。 This apparently not true. 这显然不是真的。

Embarcadero documentation regarding FMX ShowModal and mobile platforms says 关于FMX ShowModal和移动平台的Embarcadero 文档

Caution: Modal dialog boxes are not supported in Android apps. 警告:Android应用程序不支持模态对话框。 Instead of calling ShowModal, you should call Show, and have the form return and call your event. 您应该调用Show,并让表单返回并调用您的事件,而不是调用ShowModal。 We recommend that you not use modal dialogs on either of the mobile platforms (iOS and Android) because unexpected behavior can result. 我们建议您不要在任何一个移动平台(iOS和Android)上使用模态对话框,因为可能会导致意外行为。 Not using modal dialogs eliminates potential problems in debugging and supporting your mobile apps. 不使用模态对话框可消除调试和支持移动应用程序中的潜在问题。

This issue seemed to be only accuring in Delphi XE7. 这个问题似乎只适用于Delphi XE7。 I am now using Delphi XE8 and don't have this problem anymore. 我现在正在使用Delphi XE8,不再有这个问题了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM