【问题标题】:does this code need to be run in the android UI thread?这段代码是否需要在 android UI 线程中运行?
【发布时间】:2017-02-05 19:53:45
【问题描述】:

在 delphi 源代码中我看到了这个过程的例子:

procedure TAndroidVideo.RetreiveVideoSize;
var
  MediaPlayer: JMediaPlayer;
begin
  MediaPlayer := TJMediaPlayer.JavaClass.init;
  MediaPlayer.setDataSource(StringToJString(FileName));
  MediaPlayer.prepare;
  FVideoSize := TSize.Create(MediaPlayer.getVideoWidth, MediaPlayer.getVideoHeight);
  MediaPlayer := nil;
end;

可以从主线程运行。但我认为这是一个错误,这个程序必须从 android UI 线程运行吗?还是我错过了什么?

【问题讨论】:

  • 在android中主线程和ui线程是一样的
  • @akash93 实际上,它并不总是同一个线程,这有时会导致问题。 Embarcadero 计划在未来的 Delphi 版本中解决这个问题。
  • @RemyLebeau 我不知道在未来版本的 delphi 中解决这个问题是否好,因为现在他们有很多代码依赖于这种“错误”行为。如果他们这样做,我希望他们会在发布之前对其进行高度测试......
  • 是不是字面上的“procedure TAndroidVideo.RetreiveVideoSize”,因为它包含一个错字,这将是非常可悲的。
  • @penarthur66 ...啊是的,你是对的,它包含一个错字:(

标签: android delphi firemonkey


【解决方案1】:

根据the docs for MediaPlayer,对MediaPlayer.prepare 的调用应该在 UI 线程上执行。如果此代码可能在 UI 线程上运行,则应将调用更改为 MediaPlayer.prepareAsync

附:在 Android 中,UI 线程主线程 是一回事。例如,请参阅this post

附言我没有意识到在 Delphi 中,主线程 是不同的。不过,我的猜测是,阻止 Delphi 中的主线程与阻止 Android 中的 UI/主线程一样糟糕。您发布的代码将阻止正在执行它的任何线程,直到prepare 返回。

关于您关于使用异步方法(prepareAsync 等)的问题:回调(OnPreparedListener.onPrepared(MediaPlayer) 等)将发生在 UI 线程上。 调用原始异步方法的线程,不管是什么线程(不一定是 UI 线程,但可能需要是 HandlerThread)。 这还不错,因为在回调中处理程序方法,您通常要么调用另一个异步方法,要么调用低延迟方法(例如MediaPlayer.start)。

【讨论】:

  • 感谢泰德!是的,在 android main 和 ui 线程上是相同的,但在 delphi 上它是不同的(在 delphi 主线程上 = delphi .so 的主线程)......但我想说的是,即使你从不同的线程运行它android UI 线程的所有事件(如 OnPreparedListener、OnErrorListener 等)都将在 android UI 线程中触发,而不是在调用 prepare 或 asyncPrepare 的线程中触发:(这就是为什么我问是否所有事情都不能从 UI 线程中触发跨度>
  • 谢谢!但是我向您确认,回调(OnPreparedListener.onPrepared(MediaPlayer)等)不会发生在调用原始异步方法的线程上:(我只是检查了一下,它是不同的线程:(可能是因为调用原始异步方法没有自己的 Looper 运行(主 UI 线程默认运行 Looper)
  • @lok​​i - 奇怪。这似乎与我读到的不同。回调是否总是发生在主循环线程上?如果是这样,那还不错,因为通常您要么进行另一个异步调用,要么调用不阻塞的方法(例如start())。
  • 是的,总是发生在主 ui 线程上。不,还不错,但这只是让我问一下,如果以这种方式从主 ui 线程做所有事情不是更好,那么所有事件都会在任何情况下在主 ui 线程上触发。也许在主 ui 线程上引发事件的事实是因为我不知道 delphi 框架
猜你喜欢
  • 2018-09-13
  • 1970-01-01
  • 2012-10-02
  • 2015-10-29
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
相关资源
最近更新 更多