【问题标题】:startActivityForResult, result not within main threadstartActivityForResult,结果不在主线程内
【发布时间】:2016-09-23 09:15:41
【问题描述】:

我正在使用 Delphi 10.1 Berlin。

在 XE7 下一切正常。

现在当我开始一个活动时,结果似乎是在一个线程中处理的,同步/队列会挂起整个应用程序。因为我需要显示一个 TDialogServiceAsync.InputQuery,如果我不同步,我会收到一个异常,告诉我必须从主线程显示我的消息(在 XE7 下工作得很好)

这是“正在”工作的简化代码(经过测试):

致电:

FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage(
  TMessageResultNotification, HandleActivityMessage);
intnt := TJIntent.JavaClass.init;
intnt.setAction(StringToJString('com.domain.mylib.MYCLASS'));
intnt.setPackage(StringToJString('com.domain.mylib'));
TAndroidHelper.Activity.startActivityForResult(intnt, REQUEST_CODE);

处理程序:

HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
  // I tried TThread.Sync/Queue here... Hang
  if M is TMessageResultNotification then
  begin
    OnActivityResult(
      TMessageResultNotification(M).RequestCode,
      TMessageResultNotification(M).ResultCode,
      TMessageResultNotification(M).Value
    );
  end;
end;


OnActivityResult(RequestCode, ResultCode: Integer; Data: JIntent);
var
  Values: array of String;
begin
  if (RequestCode = REQUEST_CODE) and (ResultCode = TJActivity.JavaClass.RESULT_OK) then
  begin
    //Either
    TDialogServiceAsync.ShowMessage('...');
    // Or
    SetLength(Values, 1);
    Values[0] := '';
    TDialogServiceAsync.InputQuery('something', ['info'], Values, Self.OnInputQuery2_Close);
  end;
end;

除了这个例外(原文和翻译...):

'Les messages doivent être affichés dans le thread principal de l'interface utilisateur'

'消息必须从用户界面主线程显示'

【问题讨论】:

  • 提前感谢您的帮助,这个柏林的新行为很奇怪......
  • Thanks in advance for any help。我们不想要的。当您得到帮助时,我们希望得到明确的感谢。
  • 似乎有点好奇...我有一个应用程序使用这种机制来响应 ZXing 扫描条形码。这在消息管理器调用的例程中的“TThread.Queue”调用中有一个TDialogService.MessageDialog 调用。将其更改为 TDialogServiceAsync.MessageDialog 并重新运行消息框仍会以可读的方式弹出,并且可以可接受地关闭。我的TThread.QueueTMainForm.OnActivityResult 方法中。
  • 但是您是对的,因为如果您在从本质上是 Java 回调函数调用消息框时不同步消息框,Berlin 会产生异常 - 您必须将上下文切换到 FMX 线程。跨度>
  • 我从 HandleActivityMessage 和 OnActivityResult(围绕整个 proc 内容和 TDialogServiceAsync 调用)尝试了 Sync/Queue(nil, proc),但应用程序总是挂在调用中...

标签: android multithreading delphi delphi-10.1-berlin


【解决方案1】:

我再次从 XE7 中复制粘贴了原始代码,但仍然无法正常工作(“您必须显示来自主线程的消息”)

我在不同的地方再次测试了TThread.Synchronize(nil, proc);,应用程序总是无法弥补的噱头。

然后在不同的地方用TThread.Queue(nil, proc); 再次测试,直到它最终只封装了对TDialogServiceAsync 的调用。

我终于找到了一个解决方案,但是这个处理程序像一个线程一样工作,只需要为一条消息同步,但不需要同步来创建一个新的 Activity 并显示它,这有点令人不安!

如果有人可以就这一点给我一个解释,请随时添加一个我很乐意接受作为解决方案的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 2019-08-18
    • 2019-12-24
    • 1970-01-01
    相关资源
    最近更新 更多