After several times running RESTRequest.Execute
without any errors, my Android
application crashes randomly.
Although I'm developing with Firemonkey
, I could only get to the error by checking it at Android Studio's DDMS logcat.
535-614/? E/InputDispatcher﹕ channel '221d0340 com.mycompany.myappname/com.embarcadero.firemonkey.FMXNativeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
I found out that it usually indicates a Memory Leak in the application, however I'm clueless on how to prevent it from happening.
This is how I call the RESTRequest
s on the main Form:
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;
And this is how it's executed on the 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;
How can I avoid these random Memory Leaks from crashing my Android
application?
As the code is written, it seems as the scope of json_data_response_object
is wider than ExecuteReadingThread
.
Under ARC memory model an object is automatically disposed of when it goes out of scope. But here it does not go out of scope between calls to ExecuteReadingThread
. Instead the pointer to the object is constantly overwritten until there are no memory left (lots of leaks).
How can I avoid these random Memory Leaks from crashing my Android application?
There is no point in having a wide scope of the json_data_response_object
, since accessing it outside the anonymous thread is dangerous (it is ok in the OnTerminate
event handler though). I would recommend to declare the object inside the anonymous thread. Likewise the aReadingThread
is better declared inside ExecuteReadingThread
to avoid confusion.
One final point: Set the Result
variable of GetDeviceData
to nil at the beginning of the method to guarantee that a valid value is assigned in all circumstances.