在我的Android项目中,我有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);
...
}
}
我通常知道,我不应该为Android Service
明确定义构造函数。但就我而言,我想使用构造函数在我的内部存储中创建一个目录。
当我尝试它时,我得到 NullPointerException ,我不明白为什么?任何人都可以向我解释为什么在我的explicite构造函数中调用getDir(...)
时出现 NullPoineterException 的原因?
答案 0 :(得分:6)
getDir()
是Context
中的一种方法。
该服务未设置为在Context
之前用作onCreate()
。
基本上,框架通过以下方式设置服务(以及相关活动):
Context
onCreate()
在步骤1中,即在成员变量初始化或构造函数期间,您无法执行任何需要对象正确设置Context
的操作。
答案 1 :(得分:1)
您必须使用服务生命周期函数onCreate()。 onCreate函数在服务生命周期中只运行一次,并作为构造函数运行。如果你想在任何地方更新它,你可以把它放在onStartCommand(Intent intent,int flags,int startId)。
答案 2 :(得分:1)
在服务构造函数中,Context可能仍为null,而getDir正在使用Context进行内部工作。您可以在以下来源中查看:
243 @Override
244 public File getDir(String name, int mode) {
245 return mBase.getDir(name, mode);
246 }
所以如果mBase为null,那么你将获得NPE
mBase将在构造函数中设置:
56 public ContextWrapper(Context base) {
57 mBase = base;
58 }
Service扩展了ContextWrapper,但服务构造函数直接使用null值调用此构造函数:
http://androidxref.com/4.4.2_r1/xref/frameworks/base/core/java/android/app/Service.java#294
294 public Service() {
295 super(null);
296 }
所以你必须等待Service.onCreate(),或者(如果可以的话)使用一些全局已知的Context,例如你的aplication对象。
答案 3 :(得分:1)
正如@laalto所说,在onCreate()之前,该服务并未设置为用作上下文..
所以制作一个 Context 的全局变量。
Context ctx;
还应为 MyService 类构建构造函数。
public MyService(Context mContext){
this.ctx = mContext;
File dir = ctx.getDir("my_dir", Context.MODE_PRIVATE);
}