使用Delphi XE7的TMediaPlayer和Thread

时间:2015-07-04 17:22:40

标签: android multithreading delphi android-mediaplayer

我使用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上的媒体播放器?

0 个答案:

没有答案