0

I am using Marshmallow on both so I don't understand why my app is stable on the emulator but not on my phone. It works but crashes fairly soon after. This the logcat:

Process: com.madhatter.nat.test, PID: 28210
java.lang.RuntimeException: Unable to start service com.madhatter.nat.test.OverlayService@89014f1 with null: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap17(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1452)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
at com.madhatter.nat.test.OverlayService.onStartCommand(OverlayService.java:45)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3028)
at android.app.ActivityThread.-wrap17(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1452) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5443) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 

and the onStartCommand in OverlayService:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    item = intent.getExtras().getParcelable(DataItemAdapter.ITEM_KEY);
    if (item == null) {
        throw new AssertionError("Null data item received!");
    } else {
        getImageDrawable();
    }
    return START_STICKY;
}

Line 45 is the one which starts with "item". I would be really grateful for some pointers. I can post more code if needed.Thanks!

EDIT: Logcat using START__REDELIVER_INTENT

01-10 09:18:09.144 1840-7536/? I/WindowState: WIN DEATH: Window{6594f29 u0 com.madhatter.nat.test/com.madhatter.nat.test.MainActivity}
01-10 09:18:09.147 1840-7538/? I/WindowState: WIN DEATH: Window{cee56ff u0 com.madhatter.nat.test}
01-10 09:18:09.151 1840-6620/? I/WindowState: WIN DEATH: Window{26fc259 u0 com.madhatter.nat.test}
01-10 09:18:09.154 1840-7539/? I/ActivityManager: Process com.madhatter.nat.test (pid 29128) has died
01-10 09:18:09.154 1840-7539/? W/ActivityManager: Scheduling restart of crashed service com.madhatter.nat.test/.OverlayService in 32668ms
01-10 09:18:09.157 1840-3383/? W/InputDispatcher: channel '7370c7b com.madhatter.nat.test/com.madhatter.nat.test.SelectionPage (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
01-10 09:18:09.157 1840-3383/? E/InputDispatcher: channel '7370c7b com.madhatter.nat.test/com.madhatter.nat.test.SelectionPage (server)' ~ Channel is unrecoverably broken and will be disposed!
01-10 09:18:09.157 1840-3383/? W/InputDispatcher: channel 'dc69e50 com.madhatter.nat.test/com.madhatter.nat.test.LauncherPage (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
01-10 09:18:09.157 1840-3383/? E/InputDispatcher: channel 'dc69e50 com.madhatter.nat.test/com.madhatter.nat.test.LauncherPage (server)' ~ Channel is unrecoverably broken and will be disposed!
01-10 09:18:09.159 1840-4579/? I/WindowState: WIN DEATH: Window{dc69e50 u0 com.madhatter.nat.test/com.madhatter.nat.test.LauncherPage}
01-10 09:18:09.159 1840-4579/? W/InputDispatcher: Attempted to unregister already unregistered input channel 'dc69e50 com.madhatter.nat.test/com.madhatter.nat.test.LauncherPage (server)'
01-10 09:18:09.162 1840-1851/? I/WindowState: WIN DEATH: Window{7370c7b u0 com.madhatter.nat.test/com.madhatter.nat.test.SelectionPage}
01-10 09:18:09.162 1840-1851/? W/InputDispatcher: Attempted to unregister already unregistered input channel '7370c7b com.madhatter.nat.test/com.madhatter.nat.test.SelectionPage (server)'
01-10 09:18:41.843 1840-1854/? I/ActivityManager: Start proc 32159:com.madhatter.nat.test/u0a125 for service com.madhatter.nat.test/.OverlayService
01-10 09:18:41.906 32159-32159/? W/System: ClassLoader referenced unknown path: /data/app/com.madhatter.nat.test-2/lib/arm
Code Poet
  • 6,222
  • 2
  • 29
  • 50
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Prerak Sola Jan 09 '17 at 17:16

2 Answers2

1

Check the documentation for Service. Here's what happens when you return START_STICKY from onStartCommand():

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. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance; 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.

This is exactly what happens in your case, you get a null for the intent parameter. You should either check for null, or return START_REDELIVER_INTENT, which has the following behavior:

if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then it will be scheduled for a restart and the last delivered Intent re-delivered to it again via onStartCommand(Intent, int, int).

Egor
  • 39,695
  • 10
  • 113
  • 130
  • Thanks a lot. Checking for null does not help. However, returning START_REDELIVER_INTENT works with one caveat: there is one initial crash. Then the service starts again after a while and does not crash again. Any ideas? :) – Code Poet Jan 09 '17 at 17:53
  • It seems that, initially, there is no last delivered intent that we need to successfully return the START_REDELIVER_INTENT at the first-time invocation of onStartCommand. So first time crash. – ashubuntu Jan 09 '17 at 18:19
  • The reason the service was crashing on my device and not on my emulator was that the service was being killed to make memory available for other apps. The solution was to start the service as foreground. The doc I used was https://android-developers.googleblog.com/2010/02/service-api-changes-starting-with.html Thanks a lot for your help guys, as it pointed me in the right direction. – Code Poet Jan 09 '17 at 22:13
  • Not every Service should run as a foreground Service, and I'd rather call it a workaround, not a solution. Did you mean that first time you'd start the Service with an Intent it would crash? This doesn't make much sense, normally there should always be an Intent on the first run. – Egor Jan 09 '17 at 23:15
  • This is how I start the service from my MainActivity: Intent svc = new Intent(this, OverlayService.class); svc.putExtra(DataItemAdapter.ITEM_KEY, item); startService(svc); Is this not right? – Code Poet Jan 10 '17 at 08:02
  • Looks fine, and you get `null` for the `intent` immediately when the Service starts? – Egor Jan 10 '17 at 08:32
  • I have put a new logcat in the OP for you to see what's going on. Thanks! – Code Poet Jan 10 '17 at 09:26
  • Unfortunately that logcat is not suggestive. – Egor Jan 10 '17 at 10:09
  • 1
    Ok, I'll mark your answer as correct, as it clearly is. I'll review my code and I'm sure I'll work out what is not right. – Code Poet Jan 10 '17 at 10:39
0

I suggest you to first check if your intent is null or not and then perform the related operation like,

if(intent != null){
    item = intent.getExtras().getParcelable(DataItemAdapter.ITEM_KEY);
    if (item == null) {
       throw new AssertionError("Null data item received!");
    } else {
       getImageDrawable();
    } 
}

Some time STICKY_SERVICE restarted by system whenever it gets destroyed itself so it may possible that intent is null

Jaymin Panchal
  • 2,797
  • 2
  • 27
  • 31