问题
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 ?
回答1:
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.
回答2:
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).
回答3:
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:
http://androidxref.com/4.4.2_r1/xref/frameworks/base/core/java/android/content/ContextWrapper.java#244
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.
回答4:
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