android.content.Context.getPackageName()在空对象引用上的问题

100

我正在使用实现接口的片段进行工作。

public class SigninFragment extends Fragment implements SigninInterface 

片段类中接口的方法实现如下所示。

@Override
public void afterSubmitClicked(String userId, Bundle bundle) {

    Log.d(TAG,"Calling time afterSubmitClicked called"+bundle);
    
    if(!userId.equals("-1")){
        //Logged in successfully
        //Move to MusicHome
        
        Intent mIntent = new Intent(getActivity(),MusicHome.class);
        mIntent.putExtra("SigninFragment.user_details", bundle);
        startActivity(mIntent);
        
    }else{
        //Logging in failed
        //show error dialog
    }
    
}

这个方法是在执行一个扩展了AsyncTask的异步任务类之后被调用的。

但我遇到了崩溃。 错误信息显示:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

日志记录器

   02-14 16:37:04.648: E/AndroidRuntime(28177): Process: com.raaga.android, PID: 28177
02-14 16:37:04.648: E/AndroidRuntime(28177): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.content.ComponentName.<init>(ComponentName.java:77)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.content.Intent.<init>(Intent.java:3996)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.raaga.fragments.SigninFragment.afterSubmitClicked(SigninFragment.java:152)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.raaga.asynctask.SignInAsyncTask.onPostExecute(SignInAsyncTask.java:92)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.raaga.asynctask.SignInAsyncTask.onPostExecute(SignInAsyncTask.java:1)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.AsyncTask.finish(AsyncTask.java:632)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.Looper.loop(Looper.java:135)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.app.ActivityThread.main(ActivityThread.java:5221)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at java.lang.reflect.Method.invoke(Native Method)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at java.lang.reflect.Method.invoke(Method.java:372)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
18个回答

53

我已经找到了我犯的错误。 我们需要从重写的OnAttach()方法中获取活动实例。 例如:

public MainActivity activity;

@Override
public void onAttach(Activity activity){
    this.activity = activity;
}
然后按照以下方式将该活动作为上下文传递。
Intent mIntent = new Intent(activity, MusicHome.class);

2
对我来说似乎是一个 Android bug,但是好的解决方法,已经为我修复了问题! - reactive-core
7
onAttach方法已经过时。 - Menna-Allah Sami
7
onAttach(Context context) 并不是。 - oldergod
3
接收一个活动参数的那个是,接收上下文参数的不是。 - oldergod
2
我不知道这是如何解决问题的,但它有效。 - Roshana Pitigala
显示剩余7条评论

50

这个问题的答案帮助我找到了我的问题,但我的源不同,所以希望这能为在寻找答案时搜索到这个页面的某人提供帮助:

我指定了一个SharedPreferences对象,并尝试在其类级别声明处实例化它,就像这样:

public class MyFragment extends FragmentActivity {
    private SharedPreferences sharedPref =
        PreferenceManager.getDefaultSharedPreferences(this);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...

在onCreate之前引用this导致了一个错误:"java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference"。在onCreate()中实例化对象解决了我的问题,就像这样:

public class MyFragment extends FragmentActivity {
    private SharedPreferences sharedPref;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...
        sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
希望这有所帮助。

1
我在调用Application类构造函数(public class MyApplication extends Application)中的getDefaultSharedPreferences()时遇到了同样的问题。您的消息帮助我看到应该将其移动到onCreate方法中。 - OlivierGrenoble
1
不错的小技巧,帮了我很大的忙。 - Allexandre S.

25

Android API级别23。

请使用

getContext()

而不是

getActivity()

getActivity() 提供父Activity的Context对象。

在这里,您可以使用

MyActivity.this

而不是

getActivity() / getApplicationContext()


3
使用getContext()时,我遇到了相同的NPE错误。 - Ricardo
1
一些手机(例如一加和联想)在使用"MyActivity.this"时会出现NPE错误。 - Dagnogo Jean-François
@DagnogoJean-François 如何为那些手机解决它? - Sagar Pujari
可能适用于其他人,但对我不起作用。我正在使用“Fragment”。 - VikaS GuttE

11

我在尝试在一个Fragment中显示Toast时遇到了同样的问题。

经过一些调试,我发现是我在调用之前移除了该Fragment:

Toast.makeText(getContext(), "text", Toast.LENGTH_SHORT).show();

由于片段已经被移除,上下文变为null,导致异常出现。

简单的解决方案:在删除片段之前调用getContext()


10
在我的情况下,错误发生在一个Fragment的这一行:
Intent intent = new Intent(getActivity(), SecondaryActivity.class);

当我双击一个项目时,触发了上面的代码,导致两个 SecondaryActivity.class 活动同时启动,一个在另一个上面。我通过按下返回按钮关闭了顶部的 SecondaryActivity.class 活动,这触发了对 SecondaryActivity.class 中的 getActivity()的调用,因为它出现在前台。对 getActivity()的调用返回了 null 。这是某种奇怪的Android错误,所以通常不应该发生。您可以在用户单击一次后阻止点击。

6
在我的例子中,我在一个recyclerview适配器中有一个onCLick方法,一开始声明了一个Context context。
 holder.cTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(context, StoryActivity.class);
                    intent.putExtra("STORY", mComments.get(position));
                    context.startActivity(intent);
                }
            });

我更改了获取当前视图上下文的方式

 holder.cTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(v.getContext(), StoryActivity.class);
                    intent.putExtra("STORY", mComments.get(position));
                    v.getContext().startActivity(intent);
                }
            });

4
对我来说问题在于我将Activity传递给了构造函数,而不是Context。
public Adapter(Activity activity, List<MediaItem> items, boolean can) {
    mItems = items;
    canEdit = can;
    mActivity = activity;
}

我正在使用getDefaultSharedPreferences()方法,但是我需要将Activity更改为Context。因此,我将MainActivity.this作为参数传递给Adapter构造函数。


3
你只需要做这个:
Intent myIntent = new Intent(MainActivity.this, nextActivity.class);

在代码片段中? - Samir Alakbarov

2

我的类没有继承Activiti。 我是这样解决这个问题的。

class MyOnBindViewHolder : LogicViewAdapterModel.LogicAdapter {
          ...
 holder.title.setOnClickListener({v->
                v.context.startActivity(Intent(context,  HomeActivity::class.java))
            })
          ...
    }

2

在活动之前放置片段名称

Intent mIntent = new Intent(SigninFragment.this.getActivity(),MusicHome.class);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接