Reputation: 909
With Firemonkey 10.4.2 (same with 10.4.1) I have a lot of error like the one below :
External exception 1 At address: $0000007FF99E60D0
Call stack: libMyApp.so $00000074942D3B64 Grijjy.Errorreporting.TgoExceptionReporter.GlobalGetExceptionStackInfo(TExceptionRecord*)
- 124 libMyApp.so $0000007493A42480 Sysutils.Exception.RaisingException(TExceptionRecord*) + 52 libMyApp.so $0000007493A6D5B4 Sysutils.RaiseExceptObject(TExceptionRecord*) + 64 libMyApp.so $0000007493A227D0 _RaiseAtExcept(TObject*, Pointer) + 64 libMyApp.so $0000007493A4164C Internal.Excutils.SignalConverter(NativeUInt, NativeUInt, NativeUInt) + 36 libMyApp.so $00000074942CE0BC Pebble.Thread.TPebbleThread_Execute_ActRec._0_Body() + 1328 libMyApp.so $00000074942CE0BC Pebble.Thread.TPebbleThread_Execute_ActRec._0_Body() + 1328
To load marker on a MapView I use a thread create with FreeOnTerminate set to False.
TPebbleThread = class(TThread)
strict private
FMapView: TMapView;
FListMarker: TListCustomMapMarker;
FLatitude: Double;
FLongitude: Double;
FShowMapViewAtEnd: boolean;
FImgList: TImageList;
FIsTerminate: boolean;
FForceShowAllPebble: boolean;
FCheckDuplicate: boolean;
public
constructor Create(aMapView: TMapView; aListMarker: TListCustomMapMarker; aLatitude, aLongitude: Double);
destructor Destroy; override;
procedure Execute; override;
end;
This thread contain some property.
TListCustomMapMarker = class(TObjectList<TCustomMapMarker>)
// ...
end
TCustomMapMarker = class
strict private
FMarker: TMapMarker; // record in FMX.Maps
FId: integer;
FCreated: string;
FAdded: string;
FUser: string;
FKm: string;
FComment: string;
FOwner: string;
FFixed: boolean;
public
constructor Create;
destructor Destroy; override;
// property
end;
I surrounded the execute method with a try..except. I saw some errors that I fixed, but these exception didn't go in my except.
It's like the exception is raise before all (may be when I call it a 2nd time ?)
On my main form, I load the map with my thread :
procedure TfrmMain.LoadMapMarker;
begin
if Assigned(FPebbleThread) then
begin
FPebbleThread.Terminate;
end;
FListMarker.RemoveMapMarker;
FPebbleThread := TPebbleThread.Create(FListMarker, ...);
end;
The full thread method is below :
procedure TPebbleThread.Execute;
var
Url : string;
i : integer;
HTTPResponse : TToolHTTPResponse;
Value : TJSONValue;
Ar : TJSONArray;
LatitudeDouble : Double;
LongitudeDouble: Double;
Latitude : string;
Longitude : string;
CustomMapMarker: TCustomMapMarker;
Id : integer;
Param : TMultipartFormData;
begin
inherited;
FIsTerminate := False;
try
Param := TMultipartFormData.Create;
try
Param.AddField('latitude', FLatitude.ToString);
Param.AddField('longitude', FLongitude.ToString);
Param.AddField('filter', 'on');
HTTPResponse := TToolHTTP.Post(CST_URL_WS_GET_PEBBLE, Param);
finally
FreeAndNil(Param);
end;
if HTTPResponse.Valid then
begin
try
Value := TJSONObject.ParseJSONValue(HTTPResponse.Content);
Ar := Value.FindValue('item') as TJSONArray;
try
if Assigned(Ar) then
begin
try
i := 0;
while (i <= Ar.Count - 1) and not Terminated do
begin
Id := Ar.Items[i].GetValue<integer>('id');
if not FCheckDuplicate or
(FCheckDuplicate and not FListMarker.Exists(Id)) then
begin
Latitude := Ar.Items[i].GetValue<string>('latitude');
Longitude := Ar.Items[i].GetValue<string>('longitude');
LatitudeDouble := TToolMath.StrToFloat(Latitude);
LongitudeDouble := TToolMath.StrToFloat(Longitude);
if (LatitudeDouble <> 0) and (LongitudeDouble <> 0) then
begin
CustomMapMarker := TCustomMapMarker.Create;
CustomMapMarker.Id := Id;
TThread.Synchronize(nil,
procedure
var
Descr: TMapMarkerDescriptor;
begin
if not Terminated then
begin
Descr := TMapMarkerDescriptor.Create(TMapCoordinate.Create(LatitudeDouble, LongitudeDouble), '');
Descr.Snippet := CustomMapMarker.Id.ToString;
Descr.Icon := FImgList.Bitmap(TSizeF.Create(CST_IMG_SIZE, CST_IMG_SIZE), CST_IMG_MARKER_FACEBOOK)
CustomMapMarker.Marker := FMapView.AddMarker(Descr);
FListMarker.Add(CustomMapMarker);
end;
end);
end;
end;
i := i + 1;
end;
except
on E: Exception do
raise Exception.Create('[On loading] ' + E.Message);
end;
end;
finally
FreeAndNil(Value);
if FShowMapViewAtEnd then
begin
TThread.Synchronize(nil,
procedure
begin
FMapView.Visible := True;
end);
end;
end;
except
on E: Exception do
raise Exception.Create('[loading] ' + E.Message);
end;
end;
finally
FIsTerminate := True;
end;
end;
I spent a lot of time to see what can cause these error but that didn't work. Did you see a mistake somewhere ? thanks
Upvotes: 1
Views: 1564
Reputation: 21
Ok, I would push a "FPebbleThread.WaitFor" in your frMain.LoadMapMarker, after the FPebbleThread.Terminate.
Such as this
if Assigned(FPebbleThread) then
begin
FPebbleThread.Terminate;
FPebbleThread.WaitFor;
end;
The TThread.Terminate method just set a boolean, your thread is certainly not propertly terminate when you create a new one.
Upvotes: 2