Note that there are some explanatory texts on larger screens.

plurals
  1. POMember variable sometimes turns null in long-running Android service
    primarykey
    data
    text
    <p>I have an Android service that collects some data in a member variable of that service which occassionally (far from always) turns into null. I myself could never produce this no matter how long this service was running on an array of Android devices, so therefore I wonder if somebody sees any mistake in following (be aware this is a stripped down example that just illustrates the issue):</p> <pre><code>public class CollectionService extends Service { private final CollectionServiceBinder binder = new CollectionServiceBinder(); private PowerManager.WakeLock wakeLock; private UserData userData; // this is the object that sometimes becomes null @Override public IBinder onBind(Intent intent) { return binder; } @Override public void onCreate() { super.onCreate(); wakeLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AppId"); } @Override public void onDestroy() { super.onDestroy(); if (wakeLock != null &amp;&amp; wakeLock.isHeld()) { wakeLock.release(); } } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } public void startCollecting() { userData = new UserData(); Notification notification = new Notification(); // initializing notification variable startForeground(0xABCD, notification); // trigger logic that collects relevant data here, just imagine some Runnable that's triggered on a certain interval and adds data to the UserData value object. } public UserData finishCollecting() { try { userData.setFinishDate(new Date()); // throws NullPointerException every now and then. return userData; } finally { if (wakeLock.isHeld()) { wakeLock.release(); } stopForeground(true); userData = null; } } public boolean isCollecting() { return userData != null; } public class CollectionServiceBinder extends Binder { public CollectionService getService() { return CollectionService.this; } } } </code></pre> <p>The service is started in an activity using...</p> <pre><code>Intent i = new Intent(this, CollectionService.class); getApplicationContext().startService(i); getApplicationContext().bindService(i, serviceConnection, BIND_AUTO_CREATE); // just so the activity has a handle and can call startCollecting()/finishCollecting() </code></pre> <p>... and is unbound in onDestroy() using ...</p> <pre><code>getApplicationContext.unbindService(serviceConnection); </code></pre> <p>The ServiceConnection class looks like this:</p> <pre><code>public class MyServiceConnection implements ServiceConnection { private CollectionService service; @Override public void onServiceConnected(ComponentName componentName, IBinder binder) { service = ((CollectionService.CollectionServiceBinder) binder).getService(); } @Override public void onServiceDisconnected(ComponentName componentName) { service = null; } public CollectionService getCollectionService() { return service; } } </code></pre> <p>And startCollecting is trigger in an OnClickListener like this to prevent starting twice:</p> <pre><code>if (!serviceConnection.getCollectionService().isCollecting()) { serviceConnection.getCollectionService().startCollecting(); } </code></pre> <p>I believe this should all be ok but sometimes userData (as commented in the code example) will be null. Again, this happens extremely rarely (of 50.000+ active device installs on Google Play I have just received 50 reports over the course of a year, but still, I want everyone to be able to enjoy the app).</p> <p>Any ideas?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload