4

My goal is to have a background service that update a fairly large amount of data twice a day (~5min update, possibly more).

So I have a GcmTaskService that launch this service :

public class SyncOfflineCoursesService extends Service {

    private final IBinder mBinder = new MonBinder();
    private final SharedPreferenceManagerToReplace sharedPreferenceManager;

    public SyncOfflineCoursesService() {

        sharedPreferenceManager = new SharedPreferenceManagerToReplace(this); //crash on this line

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    ...
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public class MonBinder extends Binder {
        SyncOfflineCoursesService getService() {
            return SyncOfflineCoursesService.this;
        }
    }

}

SharedPreferenceManagerToReplace :

public class SharedPreferenceManagerToReplace {
    private final SharedPreferences prefs;

    public SharedPreferenceManagerToReplace(Context context) {
        this.prefs = PreferenceManager.getDefaultSharedPreferences(context);//crash here
    }
}

but it seem that this is null when I instanciate SharedPreferenceManager

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

That's how I declared both of my services in my manifest :

<service
    android:name=".service.offline.SyncOfflineCoursesService"
    android:exported="false" />

<service
    android:name=".service.offline.SyncOfflineContentService"
    android:exported="true"
    android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">

    <intent-filter>
        <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
    </intent-filter>
</service>

Would you have an idea ?

Thanks !

2
  • use application level context for this Commented Mar 22, 2017 at 11:07
  • 2
    Your Service shouldn't really have a constructor. Move that initialization to one of its lifecycle methods, like onCreate() or onStartCommand(). Commented Mar 22, 2017 at 11:10

2 Answers 2

11

NullPointerException is thrown when an application attempts to use an object reference that has the null value.

You should call this in onStartCommand() Section .

 Context context;  //Public  

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
    {
    context= getApplicationContext();
    sharedPreferenceManager = new SharedPreferenceManagerToReplace(context); 
    return super.onStartCommand(intent, flags, startId);
    }
Sign up to request clarification or add additional context in comments.

4 Comments

I didn't know that, thanks a lot. By the way would you confirm that launching a service from a GcmTaskService is the best way to download large amount of data every 10 hours ?
what kind of requirements ? what are the alternatives ?
Heavy mean between few Ko to Go of data (it syncrhonises Courses that are made available to offline and may contain all sort of medias (so videos too))
@RenaudFavier then download large amount of data every 10 hours
0

You should have context of an activity. Context of service won't work. In constructor pass the context and use that context to pass along the next constructor.

public SyncOfflineCoursesService(Context mContext) {

     sharedPreferenceManager = new SharedPreferenceManagerToReplace(mContext); 

}

1 Comment

Hello and thanks ! there is no activity when the service is created (it's created from the GCMTaskService)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.