android.content.Context.getPackageName () 'für eine Nullobjektreferenz

78

Hallo, ich arbeite mit Fragmenten, die eine Schnittstelle implementieren.

public class SigninFragment extends Fragment implements SigninInterface 

Die Methodenimplementierung der Schnittstelle in der Fragmentklasse ist wie folgt.

@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
    }

}

Diese Methode wird aufgerufen, nachdem eine AsynchronousTask-Klasse (die AsyncTask erweitert) ausgeführt wurde.

Aber ich bekomme einen Absturz. Und die Fehlermeldung zeigt

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)

Ich habe es selbst versucht und in Google erkundet. Aber ich habe keine Lösung bekommen. Könnte jemand dabei helfen?

Karthikeyan Ve
quelle

Antworten:

43

Ich habe den Fehler gefunden, was ich getan habe. Wir müssen die Aktivitätsinstanz von der Override-Methode OnAttach () abrufen. Zum Beispiel:

public MainActivity activity;

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

Übergeben Sie dann die Aktivität wie folgt als Kontext.

Intent mIntent = new Intent(activity, MusicHome.class);
Karthikeyan Ve
quelle
2
Scheint mir ein Android-Bug zu sein, aber eine gute Arbeit hat das Problem für mich behoben!
reaktiver Kern
5
onAttach ist veraltet
Menna-Allah Sami
6
@ Menna-AllahSami onAttach(Context context)ist nicht.
Älterer Gott
3
@ Menna-AllahSami Derjenige, der eine Aktivität als Parameter nimmt, ja. Derjenige, der einen Kontext nimmt, ist nicht.
Älterer Gott
2
Ich weiß nicht, wie dies das Problem behebt, aber es funktioniert.
Roshana Pitigala
39

Die Antworten auf diese Frage haben mir geholfen, mein Problem zu finden, aber meine Quelle war anders. Hoffentlich kann dies Aufschluss darüber geben, dass jemand auf dieser Seite nach Antworten auf den zufälligen Kontextabsturz sucht:

Ich hatte ein SharedPreferences-Objekt angegeben und versucht, es bei der Deklaration auf Klassenebene zu instanziieren:

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

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

Das Verweisen thisvor dem onCreate verursachte bei mir den Fehler "java.lang.NullPointerException: Versuch, die virtuelle Methode 'java.lang.String android.content.Context.getPackageName ()' für eine Nullobjektreferenz aufzurufen" .

Das Instanziieren des Objekts in onCreate () löste mein Problem wie folgt:

public class MyFragment extends FragmentActivity {
    private SharedPreferences sharedPref;

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

Hoffentlich hilft das.

mix3d
quelle
1
Ich hatte das gleiche Problem beim Aufrufen von getDefaultSharedPreferences () vom Anwendungsklassenkonstruktor (öffentliche Klasse MyApplication erweitert Application). Ihre Nachricht hat dazu beigetragen, dass ich sie in die onCreate-Methode verschieben sollte.
OlivierGrenoble
1
Netter Tipp, hat mir sehr geholfen
Allexandre S.
23

Android API Level 23.

Verwenden

getContext ()

anstatt

getActivity ()

getActivity () gibt der übergeordneten Aktivität ein Kontextobjekt

Hier können Sie verwenden

MyActivity.this

anstatt

getActivity () / getApplicationContext ()

sivaBE35
quelle
3
Ich bekomme die gleiche NPE mit getContext ()
Ricardo
Einige Telefone erhalten NPE mit MyActivity.this (ein Plus und Lenovo zum Beispiel)
Dagnogo Jean-François
@ DagnogoJean-François, wie man es für diese Telefone löst?
Sagar Pujari
Könnte für andere arbeiten, aber nicht für mich. Ich habe benutzt Fragment.
VikaS GuttE
7

Ich hatte das gleiche Problem beim Versuch, einen Toast in einem Fragment zu zeigen.

Nach einigem Debuggen stellte ich fest, dass ich das Fragment entfernte, bevor ich aufrief:

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

Da das Fragment entfernt wurde , wurde der Kontext null und verursachte die Ausnahme.

Einfache Lösung: Rufen Sie das auf, getContext() bevor Sie das Fragment entfernen .

Renatoarg
quelle
7

In meinem Fall ist der Fehler in a Fragmentin dieser Zeile aufgetreten :

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

Es geschah, als ich auf ein Element doppelklickte, das den obigen Code auslöste, sodass zwei SecondaryActivity.classAktivitäten gleichzeitig übereinander gestartet wurden. Ich schloss die oberste SecondaryActivity.classAktivität durch Drücken der Zurück-Taste, die einen Anruf getActivity()in dem SecondaryActivity.classVordergrund auslöste . Der Anruf getActivity()zurück null. Es ist eine Art seltsamer Android-Fehler, daher sollte es normalerweise nicht passieren. Sie können die Klicks blockieren, nachdem der Benutzer einmal geklickt hat.

vovahost
quelle
4

Sie müssen nur Folgendes tun:

Intent myIntent = new Intent(MainActivity.this, nextActivity.class);
Jonathan Michael Bellfontaine
quelle
4

Für mich war das Problem, dass ich Activity an den Konstruktor und nicht an Context übergeben habe

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

Wenn ich diese Aktivität verwende, um DefaultSharedPreferences () abzurufen, habe ich die Aktivität in Kontext geändert und den Adapterkonstruktor weiterhin mit MainActivity.this aufgerufen

SpyZip
quelle
2

In meinem Fall hatte ich eine onCLick-Methode in einem Recyclerview-Adapter, Context context; am Anfang.

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

Und ich habe mich geändert, um den Kontext aus der aktuellen Ansicht zu erhalten

 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);
                }
            });
Mihai
quelle
1

Meine Klasse erstreckt sich nicht auf Activiti. Ich habe das Problem auf diese Weise gelöst.

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

Stellen Sie den Fragmentnamen vor die Aktivität

Intent mIntent = new Intent(SigninFragment.this.getActivity(),MusicHome.class);
ARAVIND RAJ
quelle
0

Sie lösen das Problem mit einem Versuch / Fang. Dieser Absturz tritt auf, wenn der Benutzer die App vor der Startabsicht schließt.

try
{
    Intent mIntent = new Intent(getActivity(),MusicHome.class);
    mIntent.putExtra("SigninFragment.user_details", bundle);
    startActivity(mIntent);
}
catch (Exception e) {
    e.printStackTrace();
}
user2912087
quelle
Gute Antwort. Genau das passierte mir. Ich hatte einen Countdowntimer, der eine Absicht in der onFinishMethode erzeugen würde . Wenn der Benutzer jedoch die Zurück-Taste drückte, um zur vorherigen Aktivität zu gelangen, bei der der Timer nicht erstellt wurde, würde ich eine Null-Objektreferenz erhalten, da getActivity () nicht mehr funktionieren würde. Dies kann auch für Threads nützlich sein, die nicht geschlossen wurden, nachdem der Benutzer die Aktivität verlassen hat. Vielen Dank!
Chris Gong
0

Sie können Ihr Problem einfach lösen und Ihre Aktivität an einer beliebigen Stelle in der Aktivität verwenden. Speichern Sie die Aktivität einfach wie folgt:

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

}
igg
quelle
0

Aufgrund onAttachist in API23 und höher veraltet ... In meinem Fragment deklariere und setze parentActivityich jedes Mal vorab, wenn ich in Fragment gehe. Höchstwahrscheinlich wurde der Kontext durch Drücken der Zurück-Taste null. Deshalb ist unten meine Lösung.

private Activity parentActivity;

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

}
Michael Chiew
quelle
0
  public MessageAdapter(Context context, List<Messages> mMessageList) {

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

  }
Francis Eyogo
quelle
0

Verwendung kann in global verwendet werden

Context context;

und erstellen Sie einen Konstruktor und übergeben Sie den Kontext. LoginClass ist der Name der Klasse

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

und auch wenn wir die Klasse rufen dann verwenden , getApplicationContext wie LoginClass lclass = new LoginClass(getApplicationContext) es das ist.

Vishal Rajora
quelle