true usage of onStartCommand in Android - android

I am a little confused. I want to use a Service to register content Observer and prevent from stopping it. Where should I register contentObserver, in onCreate or onStartCommand? in other words, which one of these codes is true:
private ContentObserver smsObserver;
public void onCreate() {
super.onCreate();
smsObserver = new ObserverSms(getApplicationContext());
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, smsObserver);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
or
private ContentObserver smsObserver;
#Override
public void onCreate() {
super.onCreate();
smsObserver = new ObserverSms(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, smsObserver);
return START_STICKY;
}
or in onStart()?
Does execute onCreate or onStart again each time the page opens with onStartCommand?
and Doesn't the "return" in "return START_STICKY;" cause stop the contentObserver in second codes?

The initialization flow of a service after startService is called:
Constructor -> onCreate -> onStartCommand
The onStartCommand will be called every time after startService is called.
However the onCreate will be only called once.
Normally, the onCreate is used like the constructor because we usually don't implement the constructor of a service.
And the onStartCommand is to handle every startService request from different packages/processes which are not sure if there is a second startService or not.
In your case, if you only call startService once, they will be the same.

Related

Why Android app crash when close app if I getExtras in Service?

In Activity I start a service
Intent serv=new Intent(this, MyService.class);
serv.putExtra("mac", "mac");
startService(serv);
In the service, I get the parameter
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String mac=intent.getExtras().getString("mac");
return super.onStartCommand(intent, flags, startId);
}
Then I kill the app, the app will crash, and the service will also crash.
If I remove this line, then it will be no problem, the service also alive after I killed the app.
String mac=intent.getExtras().getString("mac");
Why the app crash?
super.onStartCommand(intent, flags, startId) returns the START_STICKY flag by default which, according to the docs, mean that:
"if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent."
Since the Intent isn't being redelivered you likely get NPE when calling intent.getExtras().
To redeliver the Intent return the START_REDELIVER_INTENT flag from onStartCommand():
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
return START_REDELIVER_INTENT;
}
You are putting extras to wrong intent bleService.putExtra("mac", "mac");
Instead you should write serv.putExtra("mac", "mac");
Also you should always check if there are extras
if(getIntent().hasExtra("mac"){
//do some stuff
}

Timer inside Android service

I have an Android service that starts a timer that does stuff:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timer.scheduleAtFixedRate(new VeryImportantTask(), 0, RATE);
return START_STICKY;
}
I know Services are singleton but, does onStartCommand method called each time that I call startService()? If so, I should control that my timer is just started the first time, shouldn't I? I'm thinking in a static boolean flag in the service. Is there a better way?
In your case i.e START_STICKY you can simply check the intent value nullity
like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(null==intent){
// service restarted do what you want
}
return START_STICKY;
}
because first time the intent will not be null and it will be null every time in case of a restart with START_STICKY.

confuse about Android IntentService [duplicate]

This question already has answers here:
Service vs IntentService in the Android platform
(11 answers)
Closed 7 years ago.
below is two method of the IntentService source
#Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
when i start the subclass of intentservice with the debug mode, i found that,it call the onstart method first and then do the onStartCommand method,but in the onStartCommand method,it do not call "onStart(intent, startId);"
as i saw the source,i think that is should be first call onStartCommond method and then do the onStart method in the onStartCommond method, as the result show above,i confuse that ,some one help me ?thanks
as i read this document,i wrote a new class called "MyService" which extends Service,and Override the onStart method and onStartCommand method,show below:
#Override
public void onStart(Intent intent, int startId) {
Log.e(TAG,"onStart");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG,"onStartCommand");
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
........
}
after i start MyService,it just call the onStartCommand method,but the onStart method is never be called! so,i think that,because i debug the android source in the sdk,not the source in my project ,so the debug is not correct as run.but i still refuse the source in IntentService.java,the onStartCommand method still call the onStart(intent, startId);
if you have some advice,please tell me! thanks !

Service onDestroy called without onStartCommand

I'm getting reports of a NullPointerException when the onDestroy() service method gets called. The part that i don't understand is that i always start the service with a Context.startService() so the onStartCommand() should always be called and the reference should never be null.
It is worth mentioning, that the NullPointerException doesn't happen when i shutdown the service with Context.stopService() call.
So my conclusion is that the framework is calling onDestroy() without having called onStartCommand(). I'm guessing that the Service might be being destroyed, and restarted by the framework so onStartCommand() doesn't actually gets executed. But again, this is me just guessing.
Any ideas on what might be going on here? Thanks!
Here's the relevant code:
public class ServiceLocationListener extends Service
private NotificationManager mNotificationManager;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
mNotificationManager = getService(this, Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(SOME_NOTIFICATION_ID, someNotification);
...
return START_STICKY;
}
#Override
public void onDestroy() {
mNotificationManager.cancel(SOME_NOTIFICATION_ID); <<<<<<<<< NPE
...
}
}
Put mNotificationManager = getService(this, Context.NOTIFICATION_SERVICE); in onCreat() of service.

onStart() and onStartCommand() still called in 2.0 and higher

According to this blog post and the documentation of onStartCommand() if you have a Service you should implement onStart() and onStartCommand() and in 2.0 and higher only onStartCommand() will be called. It seems that this is not the case and in my Service BOTH are being called. This was a problem as it was trying to do the work twice, so I had to add a check in onStart() to not do anything if the OS version was < 2.0. This seems like a hack and a bug. Anyone else experience this or do I maybe have something wrong? I cut and pasted the code right from the sample.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Util.log(mCtx, "AlerterService", "onStartCommand() called");
handleStart(intent);
return super.onStartCommand(intent, flags, startId);
}
public void onStart(Intent intent, int startId) {
Util.log(mCtx, "AlerterService", "onStart() called");
handleStart(intent);
super.onStart(intent, startId);
}
The source code of onStartCommand() is:
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
So it still calls onStart();
On that blog post, the base implementantions of onStart and onStartCommand are not called. Pressumably, one of them is calling the other.

Categories

Resources