Service的构造函数中的NullPointerException

时间:2014-01-13 10:04:42

标签: android android-service

在我的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 的原因?

4 个答案:

答案 0 :(得分:6)

getDir()Context中的一种方法。

该服务未设置为在Context之前用作onCreate()

基本上,框架通过以下方式设置服务(以及相关活动):

  1. 创建对象
  2. 使用适当的当前配置资源设置Context
  3. 在对象上调用onCreate()
  4. 在步骤1中,即在成员变量初始化或构造函数期间,您无法执行任何需要对象正确设置Context的操作。

答案 1 :(得分:1)

您必须使用服务生命周期函数onCreate()。 onCreate函数在服务生命周期中只运行一次,并作为构造函数运行。如果你想在任何地方更新它,你可以把它放在onStartCommand(Intent intent,int flags,int startId)。

答案 2 :(得分:1)

在服务构造函数中,Context可能仍为null,而getDir正在使用Context进行内部工作。您可以在以下来源中查看:

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    }

所以如果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);
}