In my Android project, I have a Service :
public class MyService extends Service{
//I defined a explicite contructor
public MyService(){
//NullPointerException here, why?
File dir = getDir("my_dir", Context.MODE_PRIVATE);
}
@Override
public void onCreate(){
super.onCreate();
...
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
...
}
}
I know normally, I shouldn't explicitly define a constructor for Android Service. But in my case, I want to use the constructor to create a directory in my internal storage.
When I try it, I got NullPointerException, which I don't understand why? Could anyone explain to me the reason why I got NullPoineterException when call getDir(...) in my explicite constructor ?
getDir() is a method in Context.
The service is not set up to be used as a Context until onCreate().
Basically, the framework sets up services (and activities for that matter) the following way:
- Create the object
- Set up the
Context, with appropriate resources for the current configuration - Call
onCreate()on the object
You cannot do anything that requires the object to be a properly set up Context at step 1 i.e. during member variable initialization or constructor.
You have to use service lifecycle function onCreate(). onCreate function run only once in a service lifecycle and works as constructor. If you want it to update anywhere then you can put it in onStartCommand(Intent intent, int flags, int startId).
Probably Context is still null in your service constructor, and getDir is using Context for its internal workings. You can check it in following sources:
243 @Override
244 public File getDir(String name, int mode) {
245 return mBase.getDir(name, mode);
246 }
so if mBase is null then you will get NPE
mBase will be set in constructor:
56 public ContextWrapper(Context base) {
57 mBase = base;
58 }
Service extends ContextWrapper, but service constructor is calling directly this constructor with null value:
http://androidxref.com/4.4.2_r1/xref/frameworks/base/core/java/android/app/Service.java#294
294 public Service() {
295 super(null);
296 }
so you must wait for Service.onCreate(), or (if you can) use some globally known Context like from you aplication object.
As @laalto said The service is not set up to be used as a Context until onCreate()..
So make one global variable of Context.
Context ctx;
Also make Constructor for your MyService class should be.
public MyService(Context mContext){
this.ctx = mContext;
File dir = ctx.getDir("my_dir", Context.MODE_PRIVATE);
}
来源:https://stackoverflow.com/questions/21088474/nullpointerexception-in-services-constructor