Delphi Android RESTRequest:通道不可恢复地损坏,将被处理掉
Delphi Android RESTRequest: channel is unrecoverably broken and will be disposed
几次 运行 RESTRequest.Execute
没有任何错误后,我的 Android
应用程序随机崩溃。
尽管我正在使用 Firemonkey
进行开发,但我只能通过在 Android Studio 的 DDMS logcat.
中检查它来发现错误
535-614/? E/InputDispatcher﹕ channel '221d0340 com.mycompany.myappname/com.embarcadero.firemonkey.FMXNativeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
我发现它通常表示应用程序中存在 内存泄漏,但是我不知道如何防止它发生。
- 在 Delphi 处调试显示根本没有崩溃。
这就是我在主窗体上调用 RESTRequest
的方式:
procedure TFormMain.ExecuteReadingThread(Sender: TObject);
begin
aReadingThread := TThread.CreateAnonymousThread(
procedure()
begin
try
json_data_response_object := DM_KVA.GetDeviceData(communication_token, genset_id);
except
on E: Exception do
begin
// Ignore
end;
end;
TThread.Queue(aReadingThread,
procedure()
begin
// Send UI Adjustments with a Thread-safe method
end);
end);
// Default Threading Settings
aReadingThread.FreeOnTerminate := true;
aReadingThread.OnTerminate := TerminateRead;
aReadingThread.Start;
end;
procedure TFormMain.TerminateRead(Sender: TObject);
begin
// Make Reading Thread take it's place
ExecuteReadingThread(Sender);
end;
这就是它在 DataModule
上的执行方式:
function TDM_KVA.GetDeviceData(ID_Token: string; ID_Device: string): TJSONObject;
var
JSObj: TJSONObject;
begin
// Set default RESTRequest parameters
RESTRequest_KVA.Resource := 'api/v1/TServerMethods1';
RESTRequest_KVA.Method := REST.Types.TRESTRequestMethod.rmGET;
RESTRequest_KVA.ResourceSuffix := Format('DeviceData/%s', [ID_Device]);
try
// Execute command
RESTRequest_KVA.Execute;
except
on E: EIdHTTPProtocolException do
begin
// Ignore
end;
on E: TRESTResponse.EJSONValueError do
begin
// Ignore
end;
on E: EIdUnknownProtocol do
begin
// Ignore
end;
end;
// Verify response
case (RESTResponse_KVA.StatusCode) of
200:
begin
// Successful readz
JSObj := (RESTRequest_KVA.Response.JSONValue as TJSONObject);
Result := JSObj;
end;
end;
end;
如何避免这些随机的内存泄漏使我的Android
应用程序崩溃?
在编写代码时,json_data_response_object
的范围似乎比 ExecuteReadingThread
更宽。
在 ARC 内存模型下,对象超出范围时会自动处理掉。但是这里它并没有超出对 ExecuteReadingThread
的调用之间的范围。相反,指向对象的指针会不断被覆盖,直到没有剩余内存(大量泄漏)。
How can I avoid these random Memory Leaks from crashing my Android application?
扩大 json_data_response_object
的范围是没有意义的,因为在匿名线程之外访问它是危险的(尽管在 OnTerminate
事件处理程序中是可以的)。我建议 在匿名线程中声明对象 。同样,aReadingThread
最好在 ExecuteReadingThread
内声明以避免混淆。
最后一点:在方法的开头将GetDeviceData
的Result
变量设置为nil,以保证在所有情况下都赋值有效。
几次 运行 RESTRequest.Execute
没有任何错误后,我的 Android
应用程序随机崩溃。
尽管我正在使用 Firemonkey
进行开发,但我只能通过在 Android Studio 的 DDMS logcat.
535-614/? E/InputDispatcher﹕ channel '221d0340 com.mycompany.myappname/com.embarcadero.firemonkey.FMXNativeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
我发现它通常表示应用程序中存在 内存泄漏,但是我不知道如何防止它发生。
- 在 Delphi 处调试显示根本没有崩溃。
这就是我在主窗体上调用 RESTRequest
的方式:
procedure TFormMain.ExecuteReadingThread(Sender: TObject);
begin
aReadingThread := TThread.CreateAnonymousThread(
procedure()
begin
try
json_data_response_object := DM_KVA.GetDeviceData(communication_token, genset_id);
except
on E: Exception do
begin
// Ignore
end;
end;
TThread.Queue(aReadingThread,
procedure()
begin
// Send UI Adjustments with a Thread-safe method
end);
end);
// Default Threading Settings
aReadingThread.FreeOnTerminate := true;
aReadingThread.OnTerminate := TerminateRead;
aReadingThread.Start;
end;
procedure TFormMain.TerminateRead(Sender: TObject);
begin
// Make Reading Thread take it's place
ExecuteReadingThread(Sender);
end;
这就是它在 DataModule
上的执行方式:
function TDM_KVA.GetDeviceData(ID_Token: string; ID_Device: string): TJSONObject;
var
JSObj: TJSONObject;
begin
// Set default RESTRequest parameters
RESTRequest_KVA.Resource := 'api/v1/TServerMethods1';
RESTRequest_KVA.Method := REST.Types.TRESTRequestMethod.rmGET;
RESTRequest_KVA.ResourceSuffix := Format('DeviceData/%s', [ID_Device]);
try
// Execute command
RESTRequest_KVA.Execute;
except
on E: EIdHTTPProtocolException do
begin
// Ignore
end;
on E: TRESTResponse.EJSONValueError do
begin
// Ignore
end;
on E: EIdUnknownProtocol do
begin
// Ignore
end;
end;
// Verify response
case (RESTResponse_KVA.StatusCode) of
200:
begin
// Successful readz
JSObj := (RESTRequest_KVA.Response.JSONValue as TJSONObject);
Result := JSObj;
end;
end;
end;
如何避免这些随机的内存泄漏使我的Android
应用程序崩溃?
在编写代码时,json_data_response_object
的范围似乎比 ExecuteReadingThread
更宽。
在 ARC 内存模型下,对象超出范围时会自动处理掉。但是这里它并没有超出对 ExecuteReadingThread
的调用之间的范围。相反,指向对象的指针会不断被覆盖,直到没有剩余内存(大量泄漏)。
How can I avoid these random Memory Leaks from crashing my Android application?
扩大 json_data_response_object
的范围是没有意义的,因为在匿名线程之外访问它是危险的(尽管在 OnTerminate
事件处理程序中是可以的)。我建议 在匿名线程中声明对象 。同样,aReadingThread
最好在 ExecuteReadingThread
内声明以避免混淆。
最后一点:在方法的开头将GetDeviceData
的Result
变量设置为nil,以保证在所有情况下都赋值有效。