Are the Delphi services unfeasible for real applications? :(
Are the Delphi services unfeasible for real applications? :(
I really don't know what can be happening. My code is far simple, it gets info from the GPS via JNI structure, opens an connection to a remote database and that's all.
I tried to isolate every main routine, but the GPS because it is mandatory. At first the application got a weird error that occurs just after few iterations (about 3 to 6 min running) and I post about it here, after create a new project everything was apparently ok, but the error is still there, now it take a longer, about 30 min to several hours and will crash the same way, with a non specific cause, error line whatever: Class aborted (6)
As Roland Kossow suggests, could be a memory error. But I am using an application called "SystemPanel" where I can watch its behavior, including the resident memory, shared and effective memory, cpu usage and I don't see memory leaks or cpu overload. BUT, when the app crashes I cannot sometimes even stop it, because it consume almost all cpu cicles :( very very bad.
Important and I will rewrite: the application won't crash immediately, it can take from some minutes (30 or more) to a lot of hours.
Original post: https://plus.google.com/+MagnoLima/posts/4QZwiDHxV9h
I really don't know what can be happening. My code is far simple, it gets info from the GPS via JNI structure, opens an connection to a remote database and that's all.
I tried to isolate every main routine, but the GPS because it is mandatory. At first the application got a weird error that occurs just after few iterations (about 3 to 6 min running) and I post about it here, after create a new project everything was apparently ok, but the error is still there, now it take a longer, about 30 min to several hours and will crash the same way, with a non specific cause, error line whatever: Class aborted (6)
As Roland Kossow suggests, could be a memory error. But I am using an application called "SystemPanel" where I can watch its behavior, including the resident memory, shared and effective memory, cpu usage and I don't see memory leaks or cpu overload. BUT, when the app crashes I cannot sometimes even stop it, because it consume almost all cpu cicles :( very very bad.
Important and I will rewrite: the application won't crash immediately, it can take from some minutes (30 or more) to a lot of hours.
Original post: https://plus.google.com/+MagnoLima/posts/4QZwiDHxV9h
Hi - sorry to read that your problem persists.
ReplyDeleteI now found this thread ...
community.embarcadero.com - Location Sensor in background Service on Android (1/1) - - Embarcadero Community
Could this help?
It says there "Remember to not use FMX components in services - only if there is written in help that it can by used."
Since I still do not have a good enough understanding of your code - could this cause the problem?
Do you use this LocationListenerService thingy here ...
https://developer.android.com/reference/android/location/LocationListener.html
... ?
See also ...
https://forums.embarcadero.com/thread.jspa?messageID=715293
Markus Humm writes there: "afaik you cannot use FMX stuff in Android services. You have to look
inside TLocation in order to find out how the ANdroid specific
implementation is done using the Android Java style/based API via the Java bridge Delphi uses."
Still having not a very good understanding of your solution, this looks relevant also - there seem to be general issues with Android Services and GPS which need to be taken care of. ...
ReplyDeletestackoverflow.com - Get GPS location via a service in Android
Roland Kossow I am very glad for all your effort in helping me! Well, for sure I know FMX cannot be used and I am not.
ReplyDeleteI will read the links and mainly the last post on StackOverflow :)
Bellow the GPS routine I am using:
type
TLocationListener = class;
TDM = class(TAndroidService) ... blah blah..
...
public
procedure onLocationChanged(Location: JLocation);
end;
TLocationListener = class(TJavaLocal, JLocationListener)
private
[weak]
FParent: TDM;
public
constructor Create(AParent: TDM);
procedure onLocationChanged(Location: JLocation); cdecl;
procedure onProviderDisabled(provider: JString); cdecl;
procedure onProviderEnabled(provider: JString); cdecl;
procedure onStatusChanged(provider: JString; status: Integer; extras: JBundle); cdecl;
end;
//** the AndroidServiceCreate() proc
procedure AndroidServiceCreate();
begin
...blah blah...
if not Assigned(FLocationManager) then
begin
LocationManagerService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.LOCATION_SERVICE);
FLocationManager := TJLocationManager.Wrap((LocationManagerService as ILocalObject).GetObjectID);
if not Assigned(locationListener) then
locationListener := TLocationListener.Create(Self);
FLocationManager.requestLocationUpdates(TJLocationManager.JavaClass.GPS_PROVIDER, 10000, 10, locationListener, TJLooper.JavaClass.getMainLooper);
end;
Location := FLocationManager.getLastKnownLocation(TJLocationManager.JavaClass.GPS_PROVIDER);
onLocationChanged(Location);
end;
//**
constructor TLocationListener.Create(AParent: TDM);
begin
inherited Create;
FParent := AParent;
end;
procedure TLocationListener.onLocationChanged(Location: JLocation);
begin
FParent.onLocationChanged(Location);
end;
// * here I get the info I need (shorted code here)
procedure TDM.onLocationChanged(Location: JLocation);
begin
FLongitude := Location.getLongitude;
FLatitude := Location.getLatitude;
FAltitude := Location.getAltitude;
FSpeed := Location.getSpeed;
FBearing := Location.getBearing;
... etc
end;
did you logcat the issue? is that possible? Could it be that a null value is passed after some time for unknown reasons in onlocationchanged after the getlastknownlocation call? could you check if Location is assigned and only call onlocationchanged if it is.
ReplyDeletehttps://stackoverflow.com/questions/19621882/getlastknownlocation-returning-null
ReplyDeleteI've implemented the logcat, but now I will trace this to check in case of invalid coordinates and let you know!
ReplyDeleteBad coordinates would provably be no problem, but NULL. Because then Onlocationchanged will throw an exception when accessing getLatitude.
ReplyDeleteAttila Kovacs There is and it IMO should be made use of in the above code.
ReplyDeleteTo be more specific ....
ReplyDeleteMagno Lima could you check if the following modification results in a more robust background service?
Or is there anything I am not aware of, that does not allow the code below?
[...]
// * here I get the info I need (shorted code here)
procedure TDM.onLocationChanged(Location: JLocation);
begin
if not Assigned(Location) then Exit;
try
FLongitude := Location.getLongitude;
FLatitude := Location.getLatitude;
FAltitude := Location.getAltitude;
FSpeed := Location.getSpeed;
FBearing := Location.getBearing;
... etc
except
//Log the Error
end;
end;
[...]
Roland Kossow I just put your suggestion, right now it is running, lets see if we can catch the issue.
ReplyDeleteOther test I am also doing is "Location.getLatitude.IsNan", but I am not sure how Delphi will handle that, because IsNan should catch is the float is Not a number, such invalid chars or even nulls.
ReplyDeleteWhat's the reason for implementing your own class that uses JLocationListener? You should be able to use TLocationSensor in an Android service, as it does not use FMX units. Regardless, I'd make liberal use of log statements (and the Monitor app, or similar) to discover where the problem lies. I've implemented cross-platform logging that does not require FMX, in the KastriFree project (check the Core folder):
ReplyDeletegithub.com - DelphiWorlds/KastriFree
David Nottage I am not sure about that. Simply putting the units for Location will crash the app as some other unit will be used and I am not telling that I am get the component from the palette but creating it in runtime. Am I missing something else? A lot of people says TLocation will NOT work with Android Services and that solution is what I use. Btw thanks for the link, I will check it for sure and I had put toons of logcat but so far I was unable to determine where the the app crashes.
ReplyDeleteI expect that it boils down to the same issue: that the RTL code is attempting to access the NativeActivity, which is nil in a service, at least for Delphi apps. I'll have a deeper look into it in a few hours.
ReplyDeleteHello,
ReplyDeleteCould you try this code ?
function TLocationServiceModule.AndroidServiceStartCommand(const Sender: TObject;
const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
Result := TJService.JavaClass.START_STICKY;
TThread.CreateAnonymousThread(procedure ()
begin
InitializeLocationSensor;
end).Start;
end;
procedure TLocationServiceModule.InitializeLocationSensor
begin
// java intrface solution here
end;
Tomasz Andrzejewski Right now compiling with your code. My original code use to initialize the LocationSensor at OnCreate() of TDM. Now I moved to StartServiceCommand() and let's see how it works.
ReplyDeleteOK.. I'll hold off on doing anything :-)
ReplyDeleteDavid Nottage Tomasz Andrzejewski Roland Kossow well guys, so far so GOOD! The good is that now the app service is damn more stable! :) :) The logcat is working like a precise clock. The bad here is that I don't really know what tech really made the job, the Tomasz's solution much probably, but I am not sure. I will let the app running for a very long period (more the 24h) and if nothing weird happens I let you know. Ok, if something goes bad I post here.
ReplyDeleteI walked outside home for some hours and returned, plug the phone on USB and kept watching the log (using the kbmLogCat software). Also the data is sending to the server side perfectly, as it should, keeping info and protections when no GPS or GRPS data network is available.
Thank for very much for such precious help! :) I hope it keeps stable.
Magno Lima Great to hear! I'll be using the findings here for my own projects; thanks
ReplyDeleteGreat. Let us informed about your progress
ReplyDeleteTomasz Andrzejewski So far it is working very fine! I will post on my blog the a very simple sample later with the code, so someone could use and improve it.
ReplyDelete