text: 
  »
  Mobile
  »
  Android
  Author
  Service being destroyed?
  Sean Michael Hayes
  Ranch Hand
  Joined: Feb 08, 2012
  Posts: 54
  I like...
  posted
  Mar 13, 2013 11:41:22
  0
  I have an App that is listening on a certain port for messages to come through. I need this service to run as long as the Application is running on the phone. However, the problem I seem to have is that the Service seems to die seconds after it is created in the code and then started again according to the logs and then seems to die again later.
  What is weird is that the destruction of the Service is not logged despite me putting a log message in the OnDestroy() method to inform me if it dies.
  here is the Service being launched in my main code.
  try { Log.e("address", trapReceiver.getLocalIpAddress()); startService(new Intent(context, snmpService.class)); Log.e("", "Succeeded"); } catch (Exception e) { Log.e("", "failed"); e.printStackTrace(); }
  And here is the service, I am using the setForeground method as that seems to be the solution according to Google
  public class snmpService extends Service { @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { super.onCreate(); setForeground(true); Log.i("snmpService", "started"); Log.i("", trapReceiver.getLocalIpAddress()); trapReceiver snmp4jTrapReceiver = new trapReceiver(this); try { snmp4jTrapReceiver.listen(new UdpAddress(trapReceiver.getLocalIpAddress()+"/5228")); } catch (IOException e) { e.printStackTrace(); Log.e("", "service error"); } catch (IllegalArgumentException e) { Toast t = Toast.makeText(this, "Unable to start listener service, please check your internet connection", 3000); t.show(); Log.e("", "service error"); } } @Override public void onDestroy() { super.onDestroy(); Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show(); Log.e("here", "end"); } }
  Steve Luke
  Bartender
  Joined: Jan 28, 2003
  Posts: 4181
  21
  I like...
  posted
  Mar 13, 2013 18:15:06
  1
  You should temper the use of setForeground(): it really is used for cases when the user should be aware of the service, and actively cares about it. The setForeground() method itself is badly depricated: it isn't even in newer API levels so if you use it then the app might not work on newer devices. See
  this for the alternative
  and a painful method of supporting bot the old and new APIs.
  I think the real fix for you is to bind to the server in the application. A service that is bound to an application is not likely to be restarted, and since you seem to indicate the life of the service should be dependent on the life of the application, I think the idea of binding to the service matches the requirement. The IBinder you create will also gives you a channel to communicate with the application or activities (as I am sure is necessary, since you have incoming messages...).
  Since you want the service to live as long as the application, and not an activity, you should do the binding in your application object. Binding in the application object has its own difficulties, since it is never clear exactly when the application ends, so you have to find signals that come close enough to indicating the application is closed. One that I have used is the
  onTrimMemory()
  method. For example, check if the parameter is >=
  TRIM_MEMORY_BACKGROUND
  and it would be a good signal that your app is no longer in use, and it is a good time to stop the service (by unbinding from it). It is a little more difficult to get a good prediction of when the application comes back to the foreground. Say for example the user stops using the app for an hour, the OS sends the TimMemory() method, but does not kill the application. Then the user re-launches the application. You may be without the service.
  A method I use to get around this is to have activities register with the application in their onResume() method and deregister in their onPause() method. This way, I can detect when the application comes to the foreground (there are 1+ registered activities) and when it goes to the background (0 registered activities). When the first activity registers, I bind the services, when the last one deregisters I unbind the service - letting it die (this usually allows the service to end sooner than waiting for the onTrimMemory() callback, which I see as a positive in terms of consuming less of a user's battery and bandwidth). I also have the application provide the IBinder to any interested activities so they can communicate with the service when required.
  Steve
  I agree. Here's the link:
  subject: Service being destroyed?
  Similar Threads
  Problem with Notifications when calling them from a Non-Activity class
  Application nor run in the background
  Beginning Android, activity / service question
  send scheduling sms through android
  Android CustomListView getView() getting nullpointerexception
  All times are in JavaRanch time: GMT-6 in summer, GMT-7 in winter
  JForum
  |
  Paul Wheaton