Reasons that the passed Intent would be NULL in onStartCommand
I'm surprised there's no discussion of the incoming flags. I'm going to monitor this in the logs with the following:
if (null == intent || null == intent.getAction ()) {
String source = null == intent ? "intent" : "action";
Log.e (TAG, source + " was null, flags=" + flags + " bits=" + Integer.toBinaryString (flags));
return START_STICKY;
}
Update: Flags were 0 so there was nothing actionable there. I've left the null check in there with no loss of function.
Edit: Ok, I found it in the documentation of START_STICKY of all places! "if there are not any pending start commands to be delivered to the service, it will be called with a null intent object, so you must take care to check for this."
http://developer.android.com/reference/android/app/Service.html
Intent is Null all the time in service
It looks like your service is type fire-and-forget - it does one quick thing and should quit immediately because it's done. Correct?
1. Don't leave your idle service running
Documentation says
If a component starts the service by calling
startService()
(which results in a call toonStartCommand()
), the service continues to run until it stops itself withstopSelf()
or another component stops it by callingstopService()
.
so after your workload is done call stopSelf()
.
When your service is not running there's nothing to restart.
2. Use correct start mode
Unless you stop it, your service is by default automatically restarted after it's killed by system (because system needed resources). The default mode is called START_STICKY
and does this:
This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a service performing background music playback.
Since your service is a quick one-time job, it makes no sense for it do be restarted later at an arbitrary time.
To let Android know, you should return START_NOT_STICKY
from onStartCommand
.
3. Use current API
Don't use onStart
, it was deprecated 9 years ago. It doesn't support start modes mentioned above. Implement onStartCommand
instead. Your service would look like this:
@Override
public void onStartCommand(Intent intent, int flags, int startId) {
// No super call.
Log.i("LOGO_OFFICE_IN", "onStart");
// Intent cannot be null.
if (intent.getExtras().getBoolean("LAUNCHER_COMMAND_CLOSE")) {
Tools.clearApplicationData(InternetService.this);
new AppStatus(InternetService.this).isAppRunning(getPackageName(), true);
}
stopSelf(); // Work is done, stop service.
return START_NOT_STICKY; // Don't restart if killed.
}
Now that I think of it, only step 1 is absolutely necessary. Anyway, get into habit of using current APIs and finding out how things work.
How to pass along extra values to a service with START_STICKY?
Use START_REDELIVER_INTENT
instead of START_STICKY
. Also, make sure that for each Intent
that you completely process, call stopSelf()
with the ID value supplied in the corresponding call to onStartCommand()
.
Then, if Android terminates your process (e.g., low memory), Android will restart your service and deliver to you any Intent
objects that you did not indicate (via stopSelf()
) that you processed.
Alternatively, do not rely on Intent
extras. Instead, store your data in a file, database, SharedPreferences
, server, etc., and have your service fetch the data from there.
Handle situation when Intent is null during onHandleIntent
I able to avoid NPE by using
setIntentRedelivery(true);
in IntentService
constructor
This answer is provided by @Kunu 's reference linkt - https://stackoverflow.com/a/37973523/72437
Map inside Bundle in intent is null in onStartCommand in Service
After a lot of struggle, I found that return type in onStartCommand should be START_REDELIVER_INTENT. It is because many times the intent gets lost and undelivered. So this return type forces it to redeliver it as it needs to get the data. Code is a follows:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle bundle = intent.getExtras();
if (bundle != null)
final long duration = bundle.getLong(DURATION, 0l);
return START_REDELIVER_INTENT;
}
android intent: when can the action be null?
Does the system ever start a service with a null intent action?
Sure. That is called an explicit Intent
, where you identify the specific component to be started. This is the sort of Intent
that you should be using for your own private activities, services, etc.
Is it possible that a service is started with null intent?
The service is always created using a non-null
Intent
. However, onStartCommand()
may be called with a null
Intent
, if the service was re-created due to Android terminating the process due to low memory conditions, where the earlier process' instance of the service returned START_STICKY
from its onStartCommand()
.
Related Topics
How to Get Data from Dialogfragment to a Fragment
Android Tablayout Android Design
Mobile Chrome Fires Resize Event on Scroll
Change Background of Edittext's Error Message
Error:Execution Failed for Task ':App:Kaptdebugkotlin'
Remove Unwanted White Space in Webview Android
Rotating Image. Animation List or Animated Rotate? (Android)
Sethinttextcolor() in Edittext
Converting from Glsurfaceview to Textureview (Via Gltextureview)
Mediarecorder Issue on Android Lollipop
Android: Turn Off Screen When Close to Face
Can't Grab Progress on Http Post File Upload (Android)
Android: Choose Default Launcher Programmatically
How to Stop a Service Running as Foreground
Get Signal Strength in Android
How to Set The App Icon as The Notification Icon in The Notification Drawer