Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Android service Thread synchronize


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 7 - Last Post: Dec 2, 2017 12:41 PM Last Post By: madammar ellias
madammar ellias

Posts: 111
Registered: 8/17/17
Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 30, 2017 5:26 PM
any idea why synchronize does not work in android service ?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 30, 2017 6:31 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

any idea why synchronize does not work in android service ?

AFAIK, it works fine in a service. Please show your actual code.

--
Remy Lebeau (TeamB)

madammar ellias

Posts: 111
Registered: 8/17/17
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 30, 2017 8:23 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...

interface
uses
  SysUtils, Classes,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, idGlobal,
  System.Generics.Collections;
 
 
{ Thread client }
 
type
TThreadVOICEProc = procedure (Sender: TObject;  Command:string) of object;
 
 
type
  TVOCQueueItem = TPair<Byte, TStream>;
 
 
  TVOCTHREAD = class(TThread)
  private
    FOnVOICEProc : TThreadVOICEProc;
    stext : String;
    TCP: TIdTCPClient;
    FQueue: TQueue<TVOCQueueItem>;
    Fservip : string;
    Fservport : integer;
    procedure ProcessCommands;
    procedure DoVOICEProc;
    procedure ClearQueue;
  protected
    FCommand: String;
 
    procedure Execute; override;
 
  Public
    constructor Create(CreateSuspended: Boolean; aThreadCallbackProc: TThreadVOICEProc; Aservip : string;
    Aservport : integer); reintroduce;
    destructor Destroy; override;
    procedure SendText(const S: string);
    procedure SendBufferD(Buffer: Pointer; Size: LongWord);
  end;
 
  var
  VOCTHREAD: TVOCTHREAD;
 
  Connectionlosfromserverv : string;
 
 
implementation
uses Audthreadunt, IdException, IdStack;
 
 
 
 
constructor TVOCTHREAD.Create(CreateSuspended: Boolean; aThreadCallbackProc: TThreadVOICEProc; Aservip : string; Aservport : integer);
begin
inherited Create(CreateSuspended);
FOnVOICEProc := aThreadCallbackProc;
FreeOnTerminate := false;
FQueue := TQueue<TVOCQueueItem>.Create;
Fservip := Aservip;
fservport := Aservport;
 
 
end;
 
 
 
destructor TVOCTHREAD.Destroy;
begin
  ClearQueue;
  FQueue.Free;
  inherited;
end;
 
procedure TVOCTHREAD.ClearQueue;
begin
  TMonitor.Enter(FQueue);
  try
    {$IFDEF AUTOREFCOUNT}
    FQueue.Clear;
    {$ELSE}
    while FQueue.Count > 0 do
      FQueue.Dequeue.Value.Free;
    {$ENDIF}
  finally
    TMonitor.Exit(FQueue);
  end;
end;
 
procedure TVOCTHREAD.DoVOICEProc;
begin
 
 
if Assigned(FOnVOICEProc) then
begin
FOnVOICEProc(self, stext);
end;
 
end;
 
procedure TVOCTHREAD.Execute;
var
 
  ErrMsg: string;
  I: Integer;
  Item: TVOCQueueItem;
begin
  try
    TCP := TIdTCPClient.Create;
    try
      TCP.Host := Fservip;
      TCP.Port := FservPort;
      TCP.ReadTimeout := -1;
      TCP.ConnectTimeout := 5000;
 
      while not Terminated do
      begin
        repeat
          if Terminated then Exit;
          try
            TCP.Connect;
          except
            for I := 1 to 5 do
            begin
              if Terminated then
                Exit;
              Sleep(1000);
            end;
            Continue;
          end;
          Break;
        until False;
 
        try
          Connectionlosfromserverv := 'NO';
          if Terminated then Exit;
 
          TCP.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8;
          TCP.IOHandler.LargeStream := True;
 
          ClearQueue;
 
          AudThread := TAudthread.Create(False);
          try
            while not Terminated do
            begin
              Item.Value := nil;
 
              TMonitor.Enter(FQueue);
              try
                if FQueue.Count > 0 then
                  Item := FQueue.Dequeue;
              finally
                TMonitor.Exit(FQueue);
              end;
 
              if Item.Value <> nil then
              try
                case Item.Key of
                  0: TCP.IOHandler.WriteLn('MEMBUF');
                  1: TCP.IOHandler.WriteLn('TEXT');
                end;
                TCP.IOHandler.Write(Item.Value, 0, True);
              finally
                Item.Value.Free;
              end;
 
              if TCP.IOHandler.InputBufferIsEmpty then
              begin
                TCP.IOHandler.CheckForDataOnSource(0);
                TCP.IOHandler.CheckForDisconnect;
                if TCP.IOHandler.InputBufferIsEmpty then Continue;
              end;
 
              FCommand := TCP.IOHandler.ReadLn;
 
              //handle
              ProcessCommands;
 
            end;
          finally
            AudThread.Terminate;
            AudThread.Free;
            ClearQueue;
          end;
        finally
          TCP.Disconnect(False);
          Connectionlosfromserverv := 'YES';
        end;
      end;
    finally
      TCP.Free;
    end;
  except
    on E: Exception do
    begin
      ErrMsg := E.ClassName + ' with message ' + E.Message;
 
      if E is EIdSocketError then
      begin
        Connectionlosfromserverv := 'YES';
      end
      else if E is EIdConnClosedGracefully then
      begin
        Connectionlosfromserverv := 'YES';
      end;
    end;
  end;
end;
 
 
 
 
procedure TVOCTHREAD.SendBufferD(Buffer: Pointer; Size: LongWord);
var
  Stream: TStream;
begin
  Stream := TMemoryStream.Create;
  try
    if Size > 0 then
    begin
      Stream.WriteBuffer(Buffer^, Size);
      Stream.Position := 0;
    end;
 
    TMonitor.Enter(FQueue);
    try
      FQueue.Enqueue(TVOCQueueItem.Create(0, Stream));
      Stream := nil;
    finally
      TMonitor.Leave(FQueue);
    end;
  except
    Stream.Free;
    raise;
  end;
end;
 
procedure TVOCTHREAD.SendText(const S: string);
var
  Stream: TStringStream;
begin
  Stream := TStringStream.Create(S, TEncoding.UTF8);
  try
    TMonitor.Enter(FQueue);
    try
      FQueue.Enqueue(TVOCQueueItem.Create(1, Stream));
      Stream := nil;
    finally
      TMonitor.Leave(FQueue);
    end;
  except
    Stream.Free;
    raise;
  end;
end;
 
 
 
 
 
 
procedure TVOCTHREAD.ProcessCommands;
var
S: string;
Command: String;
begin
Command := Fholdcommand;
 
 
 
 
 
if Command = 'Text' then
begin
S := TCP.Socket.ReadLn();
stext := S;
 
if Assigned(FOnVOICEProc) then
begin
Synchronize(DoVOICEProc);
end;
end;
 
end;
 
 
end.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2017 10:50 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

{code}

That was a lot of irrelevant code to show. The only Synchronize() call
I see is in TVOCTHREAD.ProcessCommands().

Why is your thread calling ReadLn() before calling ProcessCommands()?
You are assigning the read command to FCommand, but then
ProcessCommands() looks at FHoldCommand instead. Why not just let
ProcessCommands() read the command?

In any case, the only way Synchronize() would not work is if the RTL's
CheckSychronize() function is not being called periodically. The main
thread usually handles that. If it is not, you will have to call it
manually.

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2017 11:03 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
madammar ellias wrote:

the only way Synchronize() would not work is if the RTL's
CheckSychronize() function is not being called periodically. The main
thread usually handles that. If it is not, you will have to call it
manually.

--
Remy Lebeau (TeamB)

should i call checksynchronize after synchronize call ? as example


if Assigned(FOnVOICEProc) then
begin
Synchronize(DoVOICEProc);
CheckSychronize();
end;
end;

is that correct ?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2017 11:10 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

should i call checksynchronize after synchronize call ?

No. That would call DoVOICEProc() in the context of your worker
thread, defeating the whole purpose of using Synchronize().
CheckSynchronize() needs to be called in the main thread, not in your
worker thread.

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2017 12:00 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
No. That would call DoVOICEProc() in the context of your worker
thread, defeating the whole purpose of using Synchronize().
CheckSynchronize() needs to be called in the main thread, not in your
worker thread.

--
Remy Lebeau (TeamB)

then i should call it in DoVOICEProc after gets synchronized ?
madammar ellias

Posts: 111
Registered: 8/17/17
Re: Android service Thread synchronize  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 2, 2017 12:41 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

No. That would call DoVOICEProc() in the context of your worker
thread, defeating the whole purpose of using Synchronize().
CheckSynchronize() needs to be called in the main thread, not in your
worker thread.

--
Remy Lebeau (TeamB)

after few searches i assume that i should run checksynchronize periodically on a TTimer but that not exists in service What could be its alternative ?
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02