2017-02-05 4 views
-3

В исходном коде Delphi я вижу Exemple эту процедуру:этот код нужно запускать в потоке пользовательского интерфейса Android?

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. или я что-то пропустил?

+0

В андроиде основной поток такой же, как и нить ui – akash93

+0

@ akash93 на самом деле, это не всегда одна и та же тема, и это иногда вызывает проблемы. Embarcadero планирует рассмотреть это в будущей версии Delphi. –

+0

@RemyLebeau Я не знаю, хорошо ли это обращаться с futur-версией delphi, потому что теперь их много кода, который зависит от этого «неправильного» поведения. если они это сделают, я надеюсь, что они будут очень проверять его до выпуска ... – loki

ответ

1

В соответствии с the docs for MediaPlayer, Вызов MediaPlayer.prepare должен не выполняться в потоке пользовательского интерфейса. Если этот код может работать в потоке пользовательского интерфейса, вызов должен быть изменен на MediaPlayer.prepareAsync.

P.S. В Android, пользовательский интерфейс и Основная тема - это то же самое. См., Например, this post.

P.P.S. Я не понимал, что в Delphi Основная тема была чем-то другим. Мое предположение, однако, состоит в том, что так же плохо идея блокировать основной поток в Delphi, поскольку он блокирует UI/основной поток в Android. Код, который вы отправили, будет блокировать любой поток, который будет выполняться до тех пор, пока не вернется prepare.

Что касается вашего вопроса об использовании методов async (prepareAsync и т. Д.): Обратные вызовы (OnPreparedListener.onPrepared(MediaPlayer) и т. Д.) Произойдут в потоке пользовательского интерфейса. поток, который вызвал оригинальный асинхронный метод, независимо от того, какой поток (который не обязательно должен быть потоком пользовательского интерфейса, но, вероятно, должен быть HandlerThread). Это неплохо, потому что в методах обработчика обратного вызова вы обычно вызываете другой метод async или вызываете метод с низкой задержкой (например, MediaPlayer.start).

+0

Спасибо Теду! Да, на андроиде main и ui нить те же, но на delphi это другое (на delphi main thread = главная нить delphi .so) .. но замечание, которое у меня есть, заключается в том, что даже если вы запустите его из другого потока, в котором поток андроида UI все событие, например OnPreparedListener, OnErrorListener и т. д., будет работать в потоке UI андроид, а не в потоке, который вызывает prepare или asyncPrepare :(это почему я спрашиваю, не все ли не все из-за потока пользовательского интерфейса – loki

+0

@loki - я обновил свой ответ. –

+0

спасибо, однако я подтверждаю, что обратные вызовы (OnPreparedListener.onPrepared (Me diaPlayer) и т. д.), не будет происходить в потоке, который называется оригинальным асинхронным методом :(Я просто проверяю, и это разные потоки :(может быть, потому, что поток, который вызвал оригинальный асинхронный метод, не имеет своего собственного Looper (главный пользовательский интерфейс поток по умолчанию имеет работу Looper) – loki

Смежные вопросы

 Смежные вопросы