2014년 8월 13일 수요일

File transfer status display animation


  • TImpFileStream class ( made by J.H Park )
  • Mobile screen freezing resolved
  • Do not need to use thread.




procedure TForm1.NoThredDown_btClick(Sender: TObject);
var
  i : integer;
  mHTTP: TIdHTTP;
  SaveFile, URL : string;
  fsSource : TImpFileStream; // TFileStream;
begin
  SpeedButton1Click( Sender );
  SaveFile := ResPath + FileNameEdit.Text;
  URL := URLEdit.Text + FileNameEdit.Text;
  if FileExists( SaveFile ) then
    fsSource := TImpFileStream.Create( SaveFile, fmOpenWrite )
  else
   fsSource := TImpFileStream.Create( SaveFile, fmCreate );
  try
    //-----------------------------------------------------
    fsSource.OnPositionChange := FilePositionChange;
    if fsSource.Size = 0 then ProgressBar1.Max := 3454761
    else ProgressBar1.Max := fsSource.Size;
    ProgressBar1.Value := 0;
    Pie1.Opacity := 0.6;
    Pie1.EndAngle := -90;
    Pie1.StartAngle := -90;
  //-----------------------------------------------------
  mHTTP := TIdHTTP.Create(nil);
  mHttp.Get( URL, fsSource ); // 다운받아 파일 저장
  finally
    fsSource.Free;
    mHTTP.Free;
    DownImage.MultiResBitmap.Items[0].Bitmap.LoadFromFile( SaveFile );
  end;
end;


//-------------------------------------------------------------------------------------------------------------------------------
procedure TForm1.FilePositionChange(Sender: TObject; OldPos, NewPos: integer);
var
  rate : single;
begin
  ProgressBar1.Value := NewPos;
  Label1.Text := IntToStr( NewPos ) + ' Bytes';
  // 파이그래프 표시 --------------------------------------------------
  Pie1.EndAngle := 360 * NewPos / ProgressBar1.Max + Pie1.StartAngle;
  rate := ( Pie1.EndAngle - Pie1.StartAngle ) * 100 / 360;
  RateText.Text := Format( '%.0f' , [rate] ) + '%';
  if rate >= 100 then Pie1.AnimateFloatDelay( 'Opacity', 0.0, 1.5, 1.0 ); // 보여주고 사라짐.
  Application.ProcessMessages;
end;



TImpFileStream 클래스는 전혀 수정할 필요없이 그대로 사용하면 되며 모바일 화면에서 UI만 구현하면 됩니다.

모바일환경에서 파일송수신 상태일때는 화면이 프리징되는 현상이 생겨 이를 해결하기 위해서 쓰레드를 사용하거나 하였는데 여의치 않은 경우가 많았죠.

TImpFileStream 클래스는 쓰레드를 사용하지 않고도 화면에서 실시간으로 다운로드 상태를 표현 할수 있어서 아주 유용할것으로 판단 됩니다. (당연한 얘기지만 필요시 쓰레드 사용도 가능합니다.)


제작한 샘플은 원격서버에서 이미지 파일을 다운로드 받아 모바일 화면에 표시합니다.
파일 다운로드 상태를 표시하기 위해서는 파일크기를 알아야 하겠죠.
샘플에서는 편의상 최초 다운로드시에는 파일사이즈를 지정 했습니다.
실제 서비스 할때는 다운로드 파일이 결정이 된상태이기 때문에 어떤방법으로던지 파일사이즈를 미리 알려주기만 하면 되므로 간단한 문제 입니다.
DB에서 파일리스트를 받아온다면 파일크기도 같이 가져오면 되고, 웹에서 다운받는다면 xml 노드에 파일명과 파일크기를 같이 기록해 두면 될것 입니다.
파일사이즈가 변하는 환경이라면 다운로드 전에 미리 파일정보만 획득하는 방법도 있을것입니다.


그리고 이미지 파일 다운로드 상태를 표현하기 위해 대형사이즈의 파일로 테스트를 해보니
고해상도의 이미지 경우는 단말기에 따라 Bitmap.LoadFromFile 시 런타임 에러가 나는 경우가 있습니다.
역시 서비스시에는 모바일 화면에 맞는 적절한 크기의 이미지를 사용해야 하겠죠. (썸내일 표시등 ,주석 참조)
다운로드 자체는 전혀 문제가 없습니다.

샘플 제작하는 김에 TPie를 이용해서 원형 프로그래스바를 만들어 보았으니 같이 참조해서 보시면 도움이 될것 입니다.

전체 프로젝트는 첨부로 올립니다.
(참고로 샘플 프로젝트 서버는 항시 접속할수 있는것이 아니니 접속이 안되면 각자의 서버에서 활용해 보시기 바랍니다.)



댓글 없음:

댓글 쓰기