android - Firemonkey外部异常与Android上的线程和记录
问题描述
使用 Firemonkey 10.4.2(与 10.4.1 相同)我有很多错误,如下所示:
外部异常 1 地址:$0000007FF99E60D0
调用堆栈: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() +132
为了在 MapView 上加载标记,我使用了一个将 FreeOnTerminate 设置为 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;
该线程包含一些属性。
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;
我用try..except包围了execute方法。我看到了一些我修复的错误,但这些异常并没有出现在我的异常中。
这就像异常首先被引发(可能是我第二次调用它的时候?)
在我的主窗体上,我用我的线程加载地图:
procedure TfrmMain.LoadMapMarker;
begin
if Assigned(FPebbleThread) then
begin
FPebbleThread.Terminate;
end;
FListMarker.RemoveMapMarker;
FPebbleThread := TPebbleThread.Create(FListMarker, ...);
end;
完整的线程方法如下:
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;
我花了很多时间来查看可能导致这些错误的原因,但没有奏效。你在某处看到错误了吗?谢谢
解决方案
好的,在 FPebbleThread.Terminate 之后,我会在你的 frMain.LoadMapMarker 中推送一个“FPebbleThread.WaitFor”。
比如这个
if Assigned(FPebbleThread) then
begin
FPebbleThread.Terminate;
FPebbleThread.WaitFor;
end;
TThread.Terminate 方法只是设置了一个布尔值,当您创建一个新线程时,您的线程肯定不会正确终止。
推荐阅读
- php - Laravel Auth::attempt 写入凭据后,将我重定向到登录
- unity3d - 试图从不同的图层渲染粒子以在我的 UI 上显示它
- parquet - 如何从镶木地板文件中仅读取某些列
- r - R:如何在多个变量分组时比较单个变量的值
- python - Scrapy 选择数据绑定
- docker - Kubernetes - 将 docker-compose yaml “command” 段“转换”为 k8s 命令和参数
- elixir - 匿名函数的可见性和生命周期
- javascript - 条纹元素被破坏
- reactjs - 创建 React 应用程序和全局类型未被拾取
- javascript - 反应图表:防止图表的画布随高度和宽度缩放