空对象引用上的android.content.Context.getPackageName()'


78

嗨,我正在使用Fragments实现一个接口。

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
    }

}

在提取一个AsynchronousTask(扩展了AsyncTask)类之后,将调用此方法。

但是我崩溃了。错误消息显示

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

Logcat

   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)

我已经尝试过并在Google中进行了探索。但是我没有任何解决方案。有人可以帮忙吗?

Answers:


43

我发现了我所做的错误。我们需要从重写方法OnAttach()获取活动实例,例如,

public MainActivity activity;

@Override
public void onAttach(Activity activity){
    this.activity = activity;
}

然后将活动作为上下文传递,如下所示。

Intent mIntent = new Intent(activity, MusicHome.class);

2
对我来说似乎是一个android bug,但是很好的解决方法为我解决了这个问题!
反应堆芯

5
不推荐使用onAttach
Menna-Allah Sami

6
@ Menna-AllahSamionAttach(Context context)不是。
oldgod's

3
@ Menna-AllahSami是的,以“活动”为参数的那个。一个没有上下文的人。
oldgod

2
我不知道如何解决此问题,但可以解决问题。
Roshana Pitigala

39

这个问题的答案帮助我找到了问题,但是我的出处有所不同,因此希望这可以帮助发现此页面的人寻找“随机”上下文崩溃的答案:

我指定了一个SharedPreferences对象,并尝试在其类级别的声明中实例化它,如下所示:

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

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

对我来说this,在onCreate之前引用导致“ java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'java.lang.String android.content.Context.getPackageName()'”错误。

实例化onCreate()内部的对象解决了我的问题,如下所示:

public class MyFragment extends FragmentActivity {
    private SharedPreferences sharedPref;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...
        sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

希望能有所帮助。


1
从Application类构造函数(公共类MyApplication扩展Application)调用getDefaultSharedPreferences()时,我遇到了同样的问题。您的消息有助于我们将其移至onCreate方法。
OlivierGrenoble

1
温馨

23

android API级别23。

使用

getContext()

代替

getActivity()

getActivity()给父Activity一个Context对象

在这里你可以使用

MyActivity.this

代替

getActivity()/ getApplicationContext()


3
我使用getContext()得到了相同的NPE
里卡多

某些电话通过MyActivity.this获得NPE(例如,一个加号和一个lenovo)
DagnogoJean-François17

@DagnogoJean-François如何为那些手机解决它?
Sagar Pujari

可能为别人工作,但不为我工作。我正在使用Fragment
VikaS GuttE

7

尝试在片段中显示吐司时,我遇到了同样的问题。

经过一些调试后,我发现我在调用之前删除了该片段:

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

由于片段已被删除,因此上下文变为空,从而导致异常。

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


7

在我的情况下Fragment,此行中的内部发生了错误:

Intent intent = new Intent(getActivity(), SecondaryActivity.class);

当我双击触发上面代码的项目时发生了这种情况,因此SecondaryActivity.class同时启动了两个活动,一个活动又一个活动。我关上SecondaryActivity.class通过触发调用按后退按钮活动getActivity()SecondaryActivity.class其来到前台。呼叫已getActivity()返回null。这是一种奇怪的Android错误,因此通常不应该发生。用户单击一次后,您可以阻止点击。



4

对我来说,问题是我正在将Activity传递给构造函数,而不是Context

public Adapter(Activity activity, List<MediaItem> items, boolean can) {
    mItems = items;
    canEdit = can;
    mActivity = activity;
}

并使用此活动获取getDefaultSharedPreferences(),因此我将Activity更改为Context,但仍使用MainActivity.this调用Adapter构造函数。


2

在我的情况下,我在recyclerview适配器的上下文上下文中有一个onCLick方法;一开始。

 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);
                }
            });

1

我的课程没有扩展到Activiti。我这样解决了问题。

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

1

将片段名称放在活动之前

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

0

您可以使用try / catch解决问题。当用户在启动意图之前关闭应用程序时,将发生此崩溃。

try
{
    Intent mIntent = new Intent(getActivity(),MusicHome.class);
    mIntent.putExtra("SigninFragment.user_details", bundle);
    startActivity(mIntent);
}
catch (Exception e) {
    e.printStackTrace();
}

好答案。这正是我正在发生的事情。我有一个倒计时计时器,它将在onFinish方法中创建一个意图。但是,如果用户按下“后退”按钮转到上一个未创建计时器的活动,那么我将得到一个空对象引用,因为getActivity()将不再起作用。对于用户离开活动后未关闭的线程,这也可能很有用。谢谢一群!
克里斯·龚

0

您可以轻松解决问题并在活动中的任何位置使用活动,只需将活动存储如下:

public class MainActivity extends AppCompatActivity{
      Context context = this;

      protected void onCreate(Bundle savedInstanceState) {....}

      AnotherClass {
          Intent intent = new Intent(context, ExampleActivity.class);
          intent.putExtra("key", "value");
          startActivity(intent);
      }

}

0

由于onAttachAPI23及更高版本中已不建议使用...,在我的Fragment中,parentActivity每次进入Fragment时,我都会事先声明并设置。最有可能发生的原因是我们按下后退按钮导致上下文变为空。因此,以下是我的解决方案。

private Activity parentActivity;

public void onStart(){
        super.onStart();
        parentActivity = getActivity();
//...

}

0
  public MessageAdapter(Context context, List<Messages> mMessageList) {

    this.mContext = context;
    this.mMessageList = mMessageList;

  }

0

使用可以在全球范围内使用

Context context;

并创建一个构造函数并传递上下文。LoginClass是类的名称

LoginClass(Context context)
{this.context=context;}

而且当我们调用,然后使用类getApplicationContext 一样 LoginClass lclass = new LoginClass(getApplicationContext) 完蛋了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.