我使用DXE7开发了一个应用程序,它运行正常。但是当我使用TMediaPlayer
显示视频(每次之间15秒)后,应用程序崩溃并返回到Android桌面。分析日志,我发现应用程序没有响应,触发了ANR。
07-04 14:03:12.144 19288 19738 I info Iniciando atualização de produtos
07-04 14:03:12.319 19288 19737 I info Exibindo imagem: /data/data/com.tomm.TabelaEletronica/files/media/image15.gif
07-04 14:03:12.412 19288 19738 I info Atualização de produtos realizada com sucesso
07-04 14:03:15.100 19288 19736 I info Checagem de terminal ativo...
07-04 14:03:15.152 19288 19736 I info Checagem de terminal ativo...OK
07-04 14:03:33.516 19288 19737 I info Exibindo imagem: /data/data/com.tomm.TabelaEletronica/files/media/image9.png
07-04 14:03:42.416 19288 19738 I info No need update..
**07-04 14:03:54.720 19288 19737 I info Exibindo video: /data/data/com.tomm.TabelaEletronica/files/media/video12.mp4
07-04 14:03:55.057 19288 19737 E MediaPlayer Should have subtitle controller already set
07-04 14:03:55.058 19288 19288 E MediaPlayer Should have subtitle
controller already set**
07-04 14:03:55.511 19288 19288 D MediaPlayer getMetadata
**07-04 14:05:16.881 19288 19301 W MediaPlayer-JNI MediaPlayer finalized without being released
07-04 14:05:16.915 19288 19301 W MediaPlayer-JNI MediaPlayer finalized without being released
07-04 14:05:16.940 19288 19301 W MediaPlayer-JNI MediaPlayer finalized without being released**
07-04 14:23:16.042 19288 19288 E MediaPlayer internal/external state mismatch corrected
这是控制媒体节目的线程;
procedure TF_Main.StartMediaShow;
begin
TaskShowMedia:=TTask.Create(procedure()
var
i: Integer;
begin
LoadData;
i:=0;
while TTask.CurrentTask.Status <> TTaskStatus.Canceled do
begin
TThread.Sleep(1000);
Inc(i);
if i>TServiceSettings.GetInstance.Settings.RefreshTime then
begin
i:=0;
try
if TServiceSettings.GetInstance.Settings.PlayVideo then
ShowMedia;
LoadData;
except
on e:Exception do
begin
dm.Log.WriteLog('Erro ThreadShowMedia '+e.Message);
end;
end;
end;
end;
end).Start;
end;
这是我使用mediaplayer显示视频的代码
procedure TF_Main.ShowMedia;
var
PathToSavedMedia: string;
FileName: string;
i: Integer;
begin
//vamos lá, aqui a coisa acontece para a exibição das mídias;
//preciso percorrer a lista de midias disponivel em udmmedia e saber qual executar;
PathToSavedMedia:=TPath.Combine(TPath.GetDocumentsPath,IncludeTrailingPathDelimiter('media'));
if DMMedia.DataSetMedia.Eof then
DMMedia.DataSetMedia.First;
try
{$IFDEF POSIX}
FileName:=PathToSavedMedia+ExtractFileName(StringReplace(DMMedia.DataSetMedia.FieldByName('path').AsString,'\','/',[rfReplaceAll]));
{$ELSE}
FileName:=PathToSavedMedia+ExtractFileName(DMMedia.DataSetMedia.FieldByName('path').AsString);
{$ENDIF}
if DMMedia.DataSetMedia.FieldByName('mediatype').AsInteger=Ord(mtVideo) then
begin
dm.Log.WriteLog('Exibindo video: '+FileName);
if FileExists(FileName) then
begin
mpc.MediaPlayer.FileName:=FileName;
try
TThread.Synchronize(TThread.CurrentThread,procedure
var
i: Integer;
begin
Rectangle1.Visible:=True;
mpc.Visible:=True;
mpc.MediaPlayer.Play;
end);
finally
for i := 1 to DMMedia.DataSetMedia.FieldByName('seconds').AsInteger do
Sleep(1000);
TThread.Synchronize(TThread.CurrentThread,procedure
begin
mpc.MediaPlayer.Stop;
mpc.Visible:=False;
Rectangle1.Visible:=False;
end);
end;
end
else
begin
dm.Log.WriteLog('Arquivo não existe: '+FileName);
end;
end
else
begin
dm.Log.WriteLog('Exibindo imagem: '+FileName);
if FileExists(FileName) then
begin
TThread.Synchronize(TThread.CurrentThread,procedure
var
i: Integer;
begin
Image2.Bitmap.LoadFromFile(FileName);
Rectangle1.Visible:=True;
Image2.Visible:=True;
Application.ProcessMessages;
try
for i := 1 to DMMedia.DataSetMedia.FieldByName('seconds').AsInteger do
Sleep(1000);
finally
Image2.Visible:=False;
Rectangle1.Visible:=False;
end;
end);
end
else
begin
dm.Log.WriteLog('Arquivo não existe: '+FileName);
end;
end;
except
on e:Exception do
begin
dm.Log.WriteLog('Erro ao exibir mídia! '+e.message);
end;
end;
DMMedia.DataSetMedia.Next;
end;
分析关于媒体播放器的android文档我看到prepare方法应该在另一个线程中,而不是在主线程中。
问题是,如何通过线程正确使用Delphi XE7上的媒体播放器?