Should a service with heavy initialization keep itself running? - android

I have a Service which can be accessed via Binder. That Service requires a lot of work to initialize. Clients might rebind shortly after the unbound.
So naturally I would like to avoid the Service being stopped and restarted all the time.
Is it bad practice to keep a Service alive even if it currently does nothing? Does it have a performance impact on the device at all?
Relevant code:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
startService(new Intent(this, this.getClass()));
return new LocalBinder();
}

Related

keeping a service running after shutting down the app

i'm trying to create an app that communicates with my localhost and search in a database.
I already make the connection and find the data, but i need to stay connected and send a notification if there's any changes in the table, but I can't figure it out how to keep the connection even when I close the app, because it closes everything, even the service.
The service doesn't stay open.
This is my Class:
public class SensorService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"Starting",Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean bandera = true;
Toast.makeText(this, "Checking data...", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
stopService(new Intent(this,SensorService.class));
startService(new Intent(this,SensorService.class));
}
#Override
public void onDestroy() {
startService(new Intent(this,SensorService.class));
}
}
Every time I close the app, the service execute one more time and no more.
If you want the service to continue running after the app is closed, you need to call the startForeground(int, Notification) method from within the service. Android limits you to running longer running services in the background only as long as a notification is displayed to the user letting them know that a service is running (like a music player or a downloading service).
This is an intentional design constraint to ensure developers do not start services in the background that run indefinitely without the user being aware. Supply your own notification (can be anything) and you should be able to run the service in the background.
For more detailed information on this method, read it at: startForeground(int, Notification)
You can use onTaskRemoved and restart the service if needed.
#Override
public void onTaskRemoved(Intent rootIntent){
super.onTaskRemoved(rootIntent);
//restart your service
}
Please note that if you use onTaskRemoved, start your service as not sticky so it won't be restarted.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}

How to Upload images even when the app is killed in android

I'm calling upload images api, in IntentService which is running in the background and upload the images to server.
IntentService, onHandleEvent method is called and run in the background, what I understand is IntentService will execute the task and calls stopSelf() method.
In my app when uploading is in progress when I kill my app, the upload is terminated and IntentService stopped witch out completing the upload task.
how can I make my IntentService run even when the app is killed?
Edit 1: I tried using Sticky service, when I kill the app the service restarted and Intent data passed to the onStartCommand method is null
You can try this below code. First of all you need to add properties of Service in Manifest file
<service
android:name=".service.Service"
android:enabled="true"
android:icon="#drawable/ic_launcher"
android:isolatedProcess="true">
</service>
And also add START_STICKY in your service.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
You can create a service as mentioned in below step to keep the service running all the time
1) In the service onStartCommand method return START_STICKY.
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
2)Start the service in the background using startService(MyService) so that it always stays active regardless of the number of bound clients.
Intent intent = new Intent(this, PowerMeterService.class);
startService(intent);
3)Create the binder.
public class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
4)Define a service connection.
private ServiceConnection m_serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
m_service = ((MyService.MyBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
m_service = null;
}
};
5)Bind to the service using bindService.
Intent intent = new Intent(this, MyService.class);
bindService(intent, m_serviceConnection, BIND_AUTO_CREATE);

How to setup START_STICKY in service

I wish to ensure my service runs in the background even after a user closes the app (from the task manager or related). I am attempting to implement START_STICKY but do not know how to properly override the startService method to allow for this to work.
At present I am simply using the startService method to start and bind the LoggingIn.class to the MessagingService.class as:
startService(new Intent(LoggingIn.this, MessagingService.class));
I have researched that the method onStartCommand is the common location for implementing START_STICKY, but I have not found a need for it within my app as once the service has started I bind all other classes to it:
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((MessagingService.IMBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
Toast.makeText(GroupMessaging.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
and
bindService(new Intent(GroupMessaging.this, MessagingService.class),
mConnection, Context.BIND_AUTO_CREATE);
How can I properly implement START_STICKY and ensure that my service stays active or restarted even after the app closes?
All you need to do is return the START_STICKY flag in the onStartCommand() method:
#Override
public int onStartCommand (Intent intent, int flags, int startId){
// several lines of awesome code
return START_STICKY;
}
Further considerations:
If you use a Service without overriding onStartCommand(), it returns START_STICKY by default, although normally the code run by a Service is put in the onStartCommand() method.
That's it. You're done, go home.
The only way to ensure that your Service continues running after being dismissed in task manager, is to make it a foreground service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(ONGOING_NOTIFICATION_ID, notification);
return super.onStartCommand(intent, flags, startId);
}
Read here: https://developer.android.com/guide/components/services.html#Foreground
Returning START_STICKY alone is not the solution.

Restart Android Started Service after application was killed

I'm trying to do a StartedService in android to send periodically the user location to a server.
Until this moment I managed to create the service and starting it from the 'parent ' application and I don't know how to keep it alive after the application was killed. From what I found on internet the 'StartCommandResult.Sticky' should restart the service if this one is killed but from some reason this is not restarted.
I overried the OnStartCommand:
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
locationTask = new Task(() =>
{
//stuff to do
});
locationTask.Start();
return StartCommandResult.Sticky;
}
And the service is started like this:
Intent intent = new Intent(this.Activity, Class.FromType(typeof(LocationService)));
this.Activity.StartService(intent);
Any suggestions what should I do in order to keep my service alive after the application was killed?
As observation I'm using xamarin to do it, but I won't mind an answer in android(java).
As stated in the official documentation:
A service is "started" when an application component (such as an
activity) starts it by calling startService(). Once started, a service
can run in the background indefinitely, even if the component that
started it is destroyed. Usually, a started service performs a
single operation and does not return a result to the caller. For
example, it might download or upload a file over the network. When the
operation is done, the service should stop itself.
So, starting the service like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
Will have your service running even while your app is destroyed.
Regarding Service.START_STICKY in the official documentation:
If the system kills the service after onStartCommand() returns,
recreate the service and call onStartCommand(), but do not redeliver
the last intent. Instead, the system calls onStartCommand() with a
null intent, unless there were pending intents to start the service,
in which case, those intents are delivered. This is suitable for media
players (or similar services) that are not executing commands, but
running indefinitely and waiting for a job.
This is how I do it but its in JAVA code.
in your service you should implement a LocalBinder, onStartCommand and onCreate methods.
public class LocalBinder extends Binder {
ServiceName getService() {
return ServiceName .this;
}
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
return START_STICKY;
}
The onStartCommand should return START_STICKY;. And also, include this code on your Service:
#Override
public void onTaskRemoved(Intent rootIntent) {
// TODO Auto-generated method stub
Intent restartService = new Intent(getApplicationContext(),this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +1000, restartServicePI);
}
This will restart your Service on 1 second from the time you close it. Also, dont forget to add your service in your AndroidManifest.xml
<service android:name=".ServiceName"
android:exported="false"
android:stopWithTask="false" >
</service>
Override onStartCommand like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
For me, everything in the code was right but the problem was with the use of debugging while checking if the service was on. When I use a release version (or just dev version without connecting to the debug), the process is not killed and the service is running normally.
No idea why though. I am using Xamarin Studio 6.0.

create background services in android

i created a simple services, its job is to handle the incoming call. I created a services like below
public class CalldetectorService extends Service {
private CallHelper callHelper;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
callHelper = new CallHelper(this);
return res;
}
#Override
public void onDestroy() {
super.onDestroy();
//callHelper.stop();
}
}
Inside the helper, i m handling the call. This service is not running in background continuously. after some time, its getting halted. It works pretty well when i open app & move to background for some time, later on it wont work.
How to make my service to work in background always and catch the incoming calls
If you don't want the service to be killed by the OS: A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
In your case, 'catching' incoming calls is best achieved with a Broadcast Receiver, registered in the manifest for intent: <action android:name="android.intent.action.PHONE_STATE" />
the answer is you dont, The OS can kill a service at anytime it needs to. you can return START_STICKY which will flag you service to be restarted when it can but there is no way to make a service run forever

Categories

Resources