Background services causing crash

左心房为你撑大大i 提交于 2019-12-06 02:41:11

Android can (and will) stop your Service whenever it wants to. Because you have returned START_STICKY from onStartCommand(), Android should restart your Service after it has been killed. In this case you will get a null Intent in onStartCommand() after the restart. There is no way to prevent Android from killing your Service if it wants to.

You need to save any useful data in a persistent storage (SharedPreferences, file, database, etc.) on a regular basis so that you can recover after being restarted.

Anything in Android can be killed at any point, for instance if the system has few resources. So your code should be always ready for that. And a big change in how background services are handled will come in O. That given, I think you could read the Android documentation:

"If this service is not already running, it will be instantiated and started (creating a process for it if needed); if it is running then it remains running. Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method, with the intent given here."

so don't keep all the responsibility to the caller, but move it to the called. Start the service any time you need to pass it some info, and then let the service, which knows already if it's instantiated and running, to handle the case. Also, guard against nulls, as always in Android:

// caller, no if-check here (no responsibility)
startService(new Intent(this, TrackService.class).putExtra("SUB_ID", submissionID));

then the other side, the called service:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent == null) {
        // do nothing and return
        return START_STICKY;
    }

    // here your intent is not null, use it
    submissionID = intent.getLongExtra("SUB_ID", 0L);
    // if you got the most recent data already, do nothing
    // else, retrieve data using the passed id

    return START_STICKY;

last but not least, please note you've no need to call super.onStartCommand(intent, flags, startId); , have a look at its implementation. Keep in mind the inversion of responsibility, because it's a more general approach you can use quite a lot coding Android, not only in this example. Hope it helps!

Quick fix for this problem would be :

Return START_REDELIVER_INTENT in the onStartCommand() callback in the service instead of START_STICKY so that the entire intent is sent following a restart.

or

you can wrap the code inside onStartCommand with an if condition like this:

if (null == intent || null == intent.getAction ()) {


        return START_STICKY;
}else{
  //ur code goes in

   return START_STICKY;
 }

Reason for this null pointer exception would be: "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."

Did you register your broadcast reciever in intent action of manifest file ? or dynamically?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!