【问题标题】:Why can't I use Context.getPackageManager inside Service's constructor为什么我不能在 Service 的构造函数中使用 Context.getPackageManager
【发布时间】:2013-08-16 04:33:46
【问题描述】:

如果我尝试使用它,我会得到NullPointerException。如果移出构造函数,它可以正常工作。所以,我很好奇发生了什么事。

代码如下:

package com.example.nullptrservice;

import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.util.Log;

public class MyService extends Service {
    public MyService() {
        super();
        PackageManager pm = this.getPackageManager();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        Log.i("MyService", "---------- started --------");
        return Service.START_NOT_STICKY;
    }

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

这是 logcat 输出,当我手动运行服务时:

D/Android 运行时(4174): D/AndroidRuntime(4174):AndroidRuntime START com.android.internal.os.RuntimeInit D/AndroidRuntime(4174):CheckJNI 关闭 D/AndroidRuntime(4174):调用主条目 com.android.commands.am.Am D/dalvikvm(4184):后期启用 CheckJNI D/AndroidRuntime(4174):关闭虚拟机 I/ActivityManager(148):为服务 com.example.nullptrservice/.MyService 启动 proc com.example.nullptrservice:pid=4184 uid=10066 gids={} I/AndroidRuntime(4174):注意:附加线程“Binder Thread #3”失败 D/dalvikvm(4174):GC_CONCURRENT 释放 103K,81% 释放 489K/2560K,暂停 1ms+1ms D/jdwp(4174):收到唤醒信号,退出选择 D/dalvikvm(4174):调试器已分离;对象注册表有 1 个条目 D/AndroidRuntime(4184):关闭虚拟机 W/dalvikvm(4184):threadid=1:线程退出但未捕获异常(组=0x409ee1f8) E/AndroidRuntime(4184):致命异常:主要 E/AndroidRuntime(4184):java.lang.RuntimeException:无法实例化服务 com.example.nullptrservice.MyService:java.lang.NullPointerException E/AndroidRuntime(4184): 在 android.app.ActivityThread.handleCreateService(ActivityThread.java:2237) E/AndroidRuntime(4184): 在 android.app.ActivityThread.access$1600(ActivityThread.java:123) E/AndroidRuntime(4184): 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201) E/AndroidRuntime(4184): 在 android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(4184):在 android.os.Looper.loop(Looper.java:137) E/AndroidRuntime(4184): 在 android.app.ActivityThread.main(ActivityThread.java:4424) E/AndroidRuntime(4184): 在 java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime(4184):在 java.lang.reflect.Method.invoke(Method.java:511) E/AndroidRuntime(4184):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) E/AndroidRuntime(4184):在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) E/AndroidRuntime(4184):在 dalvik.system.NativeStart.main(本机方法) E/AndroidRuntime(4184):由:java.lang.NullPointerException引起 E/AndroidRuntime(4184):在 android.content.ContextWrapper.getPackageManager(ContextWrapper.java:86) E/AndroidRuntime(4184):在 com.example.nullptrservice.MyService.(MyService.java:12) E/AndroidRuntime(4184):在 java.lang.Class.newInstanceImpl(本机方法) E/AndroidRuntime(4184):在 java.lang.Class.newInstance(Class.java:1319) E/AndroidRuntime(4184): 在 android.app.ActivityThread.handleCreateService(ActivityThread.java:2234) E/AndroidRuntime(4184): ... 10 更多

Android 4.0.3

还有a bunchrelated 问题在这里

【问题讨论】:

标签: android


【解决方案1】:

尝试使用处理程序从 onCreate() 或服务构造函数中退出,并在处理程序中执行您的工作。

【讨论】:

  • 对不起,我不明白。你能扩大你的答案吗?
  • 把这个「PackageManager pm = this.getPackageManager();」放在一个Handler中,然后在你的Constructor末尾发送事件给这个Handler。
  • 啊!您建议推迟pm 的初始化,稍后在另一个线程中进行,对吗?坦率地说,我认为这不是一个好主意——我不知道我的对象何时会完全构造(或者必须在某个地方等待该线程完成)。此外,将其移至 onCreate() 也可以。
【解决方案2】:

在创建/初始化对象时,您不能使用Service(或Activity)作为Context

相反,覆盖onCreate() 并在那里进行初始化并摆脱显式构造函数。

【讨论】:

  • 是的,我认为我不能以及如何解决它,但为什么呢?我应该一直使用 onCreate() 吗?在文档中没有看到这个。关于构造函数 - 我的实际代码就像private ClassUsingPM mSomeField = new ClassUsingPM(this),所以它有点简洁然后转移到一些方法
  • 是的,在onCreate() 中实例化需要Context 的成员对象。
  • 您知道一些官方指南或博客文章,我可以阅读吗?我仍然不明白为什么我应该这样做(我认为这会让我更好地了解平台)。
  • 我没有看到任何专门解决这个问题的方法。通常,您从不直接实例化活动或服务,而是通过Intent。框架实例化对象,设置ContextApplication 等资源,然后才调用您的onCreate()。至少这使得所涉及的类的耦合度降低,并且在演化它们时减少了痛苦。
猜你喜欢
  • 2020-03-06
  • 2015-05-28
  • 2011-01-11
  • 2016-02-17
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多