bsw
bsw

Reputation: 153

Delphi XE5 Android Thread makes app crash

I have a thread downloading and saving a clientDataset file cds file from a remote Datasnap Server.

This thread works in Windows, IOS (Simulator, Iphone, Ipad) but not on Android.

The app crashes after completed the file download and save it on Android.

The code is simple.

Thread:

TDownloadSaveRemoteDBThread = class (TThread)
public
  Username,Password,host,port : String;
  error                      : String;
  Folder                     : String;
  ServerMethod               : String;
  filename                   : String;
protected
  procedure Execute; override;
end;

procedure TDownloadSaveRemoteDBThread.Execute;
var
  sqlCon : TSqlConnection;
  cds    : TClientDataset;
  ssm    : TSqlServerMethod;
  dpr    : TDataSetProvider;
begin
  inherited;

  error :='';
  SqlCon:=TSQLConnection.Create(nil);
  try
    sqlCon.DriverName:='Datasnap';
    sqlCon.LoginPrompt:=false;
    sqlCon.Params.Values['hostname']:=host;
    sqlCon.Params.Values['port']:=port;
    sqlCon.Params.Values['UserName']:=Username;
    sqlCon.Params.Values['Password']:=Password;
    try
      sqlCon.Open;
      cds:=TClientDataset.Create(nil);
      ssm:=TSqlServerMethod.Create(nil);
      dpr:=TDataSetProvider.Create(nil);
      try
        ssm.SQLConnection:=SqlCon;
        ssm.ServerMethodName:=ServerMethod;
        dpr.DataSet:=ssm;
        cds.SetProvider(dpr);
        cds.Open;
        cds.SaveToFile(folder+filename);
        cds.Close;
      finally
        cds.free;
        ssm.free;
        dpr.free;
      end;
    Except
      on E : Exception do
      Begin
        error:=E.Message;
        SQLCon.Close;
      End;
    end;
  finally
    SQLCon.Close;
    SQLCon.free;
  end;
end;

I have a button to start the thread in my mainform “Start Form”

procedure TStartForm.Button1Click(Sender: TObject);
var
  DownloadSaveRemoteDBThread : TDownloadSaveRemoteDBThread;
begin
  DownloadSaveRemoteDBThread:= TDownloadSaveRemoteDBThread.Create(true);
  DownloadSaveRemoteDBThread.OnTerminate:= StartForm.ferdigHentDB;
  DownloadSaveRemoteDBThread.Password:='test';
  DownloadSaveRemoteDBThread.Username:='test';
  DownloadSaveRemoteDBThread.host:=edit1.text; //127.0.0.1
  DownloadSaveRemoteDBThread.port:='211';
  DownloadSaveRemoteDBThread.Folder:=System.IOUtils.TPath.GetDocumentsPath +  PathDelim +'db'+  PathDelim;
  DownloadSaveRemoteDBThread.ServerMethod:= 'TServerMethods2.hentselect3';
  DownloadSaveRemoteDBThread.filename:='select3.cds';
  DownloadSaveRemoteDBThread.FreeOnTerminate:=true;
  DownloadSaveRemoteDBThread.Start;
end;

Then after thread is finished I have this simple procedure

procedure TStartForm.ferdigHentDB(sender: Tobject);
begin

  with sender as TDownloadSaveRemoteDBThread do
  Begin
    if error > '' then
    Begin
      showmessage(error);
    End;
  End;
end;

Any suggestions why Android crashes, is there an easy fix for this issue?

Upvotes: 0

Views: 1643

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595712

TThread in XE5 has two major bugs on Android. Sychronize() and Queue() are broken (Synchronize() is used to trigger the OnTerminate event), and TThread does not detach itself from the Android JVM before termination if any JNI objects are used by the thread. The first bug has not been fixed yet. The second bug is fixed in XE6, but there is a workaround you can use in XE5.

Upvotes: 2

Related Questions