为什么 getApplicationContext 在单例 getInstance 中抛出 nullPointerException?
Why is getApplicationContext throwing nullPointerException, in singleton getInstance?
我创建了一个扩展 SQLiteOpenHelper 的 class (GameHelper)。我希望它是一个单例,所以我可以创建它并让它在运行时存储数据库的内容,所有其他 classes 引用它。
我遵循了建议 here,(方法 1)。
所以当我需要引用数据库时,我不会创建一个新的 GameHelper 实例,而是调用 getInstance。这是相关代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_info);
populate(getIntent().getStringExtra("game"), getIntent().getStringExtra("game"));
}
public void populate(String gameToGo, String game) {
DataTable game = gameHelper.getgame(game, gameToGo); //GameInfo.java:12
TextView tv = (TextView) findViewById(R.id.tableId);
String text = game.TABLE_ID;
tv.setText(text);
}
其中指的是GameHelper中的以下方法:
private static GameHelper sInstance;
public static synchronized GameHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
// See this article for more information: http://bit.ly/6LRzfx
if (sInstance == null) {
sInstance = new GameHelper(context.getApplicationContext()); //GameHelper.java:60
}
return sInstance;
}
问题出现在 sInstance = new GameHelper(context.getApplicationContext());
行,它抛出 NullPointerException,如下所示:
11-08 10:14:54.974 16214-16214/com.example.android.whichgame E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.android.whichgame, PID: 16214
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.android.whichgame/com.example.android.whichgame.GameInfo}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2177)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
at com.example.android.whichgame.GameHelper.getInstance(GameHelper.java:60)
at com.example.android.whichgame.GameInfo.<init>(GameInfo.java:12)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1062)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2155)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
我花了一整天的时间在互联网上搜索答案,虽然我发现了很多类似问题的答案,但我没有找到任何有用的东西。最好和最受欢迎的答案似乎是我需要在 AndroidManifest 中为 <application>
设置 android:name
,但这里存在另一个问题。我在 Android Studio 工作,当我尝试添加我的应用程序名称时,该名称变成红色。我想这可能是我做错了!我的程序包(如清单中所定义)是 "com.example.android.whichgame",尽管应用程序本身(及其所在的文件夹)名为 Whichgame。
所以我的问题是:我错过了什么导致 getApplicationContext() 在通过 getInstance 调用时踢出 NPE?如果是因为我没有设置 android:name,是什么导致 Studio 和编译器拒绝该名称?
您在初始化阶段过早地使用 GameInfo
activity 作为 Context
。将需要有效 Context
的初始化推迟到 onCreate()
或 activity 生命周期中的更晚时间。
我创建了一个扩展 SQLiteOpenHelper 的 class (GameHelper)。我希望它是一个单例,所以我可以创建它并让它在运行时存储数据库的内容,所有其他 classes 引用它。
我遵循了建议 here,(方法 1)。
所以当我需要引用数据库时,我不会创建一个新的 GameHelper 实例,而是调用 getInstance。这是相关代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_info);
populate(getIntent().getStringExtra("game"), getIntent().getStringExtra("game"));
}
public void populate(String gameToGo, String game) {
DataTable game = gameHelper.getgame(game, gameToGo); //GameInfo.java:12
TextView tv = (TextView) findViewById(R.id.tableId);
String text = game.TABLE_ID;
tv.setText(text);
}
其中指的是GameHelper中的以下方法:
private static GameHelper sInstance;
public static synchronized GameHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
// See this article for more information: http://bit.ly/6LRzfx
if (sInstance == null) {
sInstance = new GameHelper(context.getApplicationContext()); //GameHelper.java:60
}
return sInstance;
}
问题出现在 sInstance = new GameHelper(context.getApplicationContext());
行,它抛出 NullPointerException,如下所示:
11-08 10:14:54.974 16214-16214/com.example.android.whichgame E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.android.whichgame, PID: 16214
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.android.whichgame/com.example.android.whichgame.GameInfo}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2177)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
at com.example.android.whichgame.GameHelper.getInstance(GameHelper.java:60)
at com.example.android.whichgame.GameInfo.<init>(GameInfo.java:12)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1062)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2155)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
我花了一整天的时间在互联网上搜索答案,虽然我发现了很多类似问题的答案,但我没有找到任何有用的东西。最好和最受欢迎的答案似乎是我需要在 AndroidManifest 中为 <application>
设置 android:name
,但这里存在另一个问题。我在 Android Studio 工作,当我尝试添加我的应用程序名称时,该名称变成红色。我想这可能是我做错了!我的程序包(如清单中所定义)是 "com.example.android.whichgame",尽管应用程序本身(及其所在的文件夹)名为 Whichgame。
所以我的问题是:我错过了什么导致 getApplicationContext() 在通过 getInstance 调用时踢出 NPE?如果是因为我没有设置 android:name,是什么导致 Studio 和编译器拒绝该名称?
您在初始化阶段过早地使用 GameInfo
activity 作为 Context
。将需要有效 Context
的初始化推迟到 onCreate()
或 activity 生命周期中的更晚时间。