Android服务中TidHttp的分段错误
我在delphi中创建了一个Android本地服务,该服务触发了一个创建Tidhhp的线程。如果我通过命令JavaService.stopSelf停止该服务,并在不关闭应用程序的情况下再次启动该服务,则当tidhttp组件执行“get”时,会出现“Segmentation fault(11)”错误。如果我关闭并重新打开应用程序,则不会发生此错误。 我的代码:Android服务中TidHttp的分段错误,android,delphi,firemonkey,idhttp,Android,Delphi,Firemonkey,Idhttp,我在delphi中创建了一个Android本地服务,该服务触发了一个创建Tidhhp的线程。如果我通过命令JavaService.stopSelf停止该服务,并在不关闭应用程序的情况下再次启动该服务,则当tidhttp组件执行“get”时,会出现“Segmentation fault(11)”错误。如果我关闭并重新打开应用程序,则不会发生此错误。 我的代码: LThread := TThread.CreateAnonymousThread( procedure var
LThread := TThread.CreateAnonymousThread(
procedure
var
pagina: string;
pegar: tidhttp;
seguro: TIdSSLIOHandlerSocketOpenSSL;
compressor: TIdCompressorZLib;
begin
try
pegar := tidhttp.create(nil);
compressor := TIdCompressorZLib.create(nil);
seguro := TIdSSLIOHandlerSocketOpenSSL.create(nil);
pegar.Request.useragent :=
'Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36';
pegar.ReadTimeout := 60000;
pegar.ConnectTimeout := 60000;
pegar.HTTPOptions := [hoForceEncodeParams];
pegar.IOHandler := seguro;
pegar.compressor := compressor;
pegar.HandleRedirects := false;
pegar.Request.Accept :=
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
pegar.Request.AcceptLanguage := 'pt-BR,en-US;q=0.8,pt;q=0.5,en;q=0.3';
pegar.Request.ContentType := 'application/json';
pegar.Request.Connection := 'keep-alive';
pegar.Request.ContentType := '';
pagina := pegar.Get
('https://meyserver.com/api/versions/count');
finally
compressor.Free;
seguro.Free;
pegar.Free;
end;
end);
LThread.FreeOnTerminate := true;
LThread.Start;
end;
德里调试显示错误发生在函数中的“System.Generics.Collections”单元中:
function TThreadList <T> .LockList: TList <T>;
begin
TMonitor.Enter (FLock);
Result: = FList;
end;
更新2:
主机应用程序中的我的代码:
procedure Tfrm_principal.Button13Click(Sender: TObject);
var
LIntent: JIntent;
begin
LIntent := TJIntent.create;
LIntent.setClassName(TAndroidHelper.Activity.getBaseContext,
TAndroidHelper.StringToJString('com.embarcadero.services.MyAppTest'));
LIntent.setAction(StringToJString('StartIntent'));
TAndroidHelper.Activity.startService(LIntent);
end;
procedure Tfrm_principal.Button16Click(Sender: TObject);
var
LIntent: JIntent;
begin
LIntent := TJIntent.create;
LIntent.setClassName(TAndroidHelper.Activity.getBaseContext,
TAndroidHelper.StringToJString('com.embarcadero.services.MyAppTest'));
LIntent.setAction(StringToJString('StopIntent'));
TAndroidHelper.Activity.startService(LIntent);
end;
服务应用程序中的我的代码:
function TDM.AndroidServiceStartCommand(const Sender: TObject;
const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
if Assigned(Intent) then
begin
if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) = true
then
begin
Result := TJService.JavaClass.START_NOT_STICKY;
JavaService.stopSelf;
end
else if Intent.getAction.equalsIgnoreCase(StringToJString('StartIntent')) = true
then
begin
Result := TJService.JavaClass.START_STICKY;
start_thread;
end;
end;
end;
procedure TDM.start_thread;
begin
TThread.CreateAnonymousThread(
procedure
var
pagina: string;
pegar: tidhttp;
seguro: TIdSSLIOHandlerSocketOpenSSL;
compressor: TIdCompressorZLib;
begin
pegar := tidhttp.create(nil);
compressor := TIdCompressorZLib.create(nil);
seguro := TIdSSLIOHandlerSocketOpenSSL.create(nil);
try
pegar.Request.useragent :=
'Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36';
pegar.ReadTimeout := 60000;
pegar.ConnectTimeout := 60000;
pegar.HTTPOptions := [hoForceEncodeParams];
pegar.IOHandler := seguro;
pegar.compressor := compressor;
pegar.HandleRedirects := false;
pegar.Request.Accept :=
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
pegar.Request.AcceptLanguage := 'pt-BR,en-US;q=0.8,pt;q=0.5,en;q=0.3';
pegar.Request.ContentType := 'application/json';
pegar.Request.Connection := 'keep-alive';
try
pagina := pegar.Get('https://myserver.com/api/versions/count');
except
enviar_log('Connection error');
end;
finally
compressor.Free;
seguro.Free;
pegar.Free;
end;
enviar_log('Exit');
end).Start;
end;
您没有尝试在
LThread.Start之后访问LThread
代码>,是吗?FWIW,FreeOnTerminate
在使用CreateAnonymousThread
时是不必要的,并且根本不需要对它进行引用。它违背了CreateAnonymousThread
的目的。相反,只需执行TThread.CreateAnonymousThread(…).Start代码>而不获取对它的任何引用。Idk,如果这是您的问题,但这对我来说很突出。另一方面,您的try..finally
块设置错误。您应该在try
之前创建这些对象,而不是在之后。获取pagina
后如何处理?这只通过这个本地过程可用,我看不到任何关于实际使用从服务器获得的内容的信息。这表明您还有其他我们看不到的相关代码。大家好,这段代码只是一个测试,线程工作正常,我在线程完成后运行JavaService.stopSelf命令,服务正确终止,没有任何错误,但是当我在不关闭应用程序的情况下重新启动服务时,SF(11)出现错误。@alexander.Pires由于您能够在调试器中看到segfault,导致segfault的调用堆栈是什么样子的?您没有尝试在LThread.Start之后访问LThread
代码>,是吗?FWIW,FreeOnTerminate
在使用CreateAnonymousThread
时是不必要的,并且根本不需要对它进行引用。它违背了CreateAnonymousThread
的目的。相反,只需执行TThread.CreateAnonymousThread(…).Start代码>而不获取对它的任何引用。Idk,如果这是您的问题,但这对我来说很突出。另一方面,您的try..finally
块设置错误。您应该在try
之前创建这些对象,而不是在之后。获取pagina
后如何处理?这只通过这个本地过程可用,我看不到任何关于实际使用从服务器获得的内容的信息。这表明您还有其他我们看不到的相关代码。大家好,这段代码只是一个测试,线程工作正常,我在线程完成后运行JavaService.stopSelf命令,服务正确终止,没有任何错误,但是当我在不关闭应用程序的情况下重新启动服务时,SF(11)出现错误。@alexander.Pires由于您能够在调试器中看到segfault,导致segfault的调用堆栈是什么样子的?
function TDM.AndroidServiceStartCommand(const Sender: TObject;
const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
if Assigned(Intent) then
begin
if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) = true
then
begin
Result := TJService.JavaClass.START_NOT_STICKY;
JavaService.stopSelf;
end
else if Intent.getAction.equalsIgnoreCase(StringToJString('StartIntent')) = true
then
begin
Result := TJService.JavaClass.START_STICKY;
start_thread;
end;
end;
end;
procedure TDM.start_thread;
begin
TThread.CreateAnonymousThread(
procedure
var
pagina: string;
pegar: tidhttp;
seguro: TIdSSLIOHandlerSocketOpenSSL;
compressor: TIdCompressorZLib;
begin
pegar := tidhttp.create(nil);
compressor := TIdCompressorZLib.create(nil);
seguro := TIdSSLIOHandlerSocketOpenSSL.create(nil);
try
pegar.Request.useragent :=
'Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36';
pegar.ReadTimeout := 60000;
pegar.ConnectTimeout := 60000;
pegar.HTTPOptions := [hoForceEncodeParams];
pegar.IOHandler := seguro;
pegar.compressor := compressor;
pegar.HandleRedirects := false;
pegar.Request.Accept :=
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
pegar.Request.AcceptLanguage := 'pt-BR,en-US;q=0.8,pt;q=0.5,en;q=0.3';
pegar.Request.ContentType := 'application/json';
pegar.Request.Connection := 'keep-alive';
try
pagina := pegar.Get('https://myserver.com/api/versions/count');
except
enviar_log('Connection error');
end;
finally
compressor.Free;
seguro.Free;
pegar.Free;
end;
enviar_log('Exit');
end).Start;
end;