Tentative d'invoquer la méthode virtuelle java.lang.Chaîne de android.contenu.Contexte.getPackageName () sur un objet nul de référence
J'ai un Activity
, qui lui-même a trois Fragment
s.
Dans l'un de ces fragments, il y a un RecyclerView
avec un adaptateur personnalisé, et en cliquant sur l'un de ses éléments serait de passer à une autre page, qui est une nouvelle instance de la même Activity
. Cependant, un certain comportement qui provoque une erreur dans mon application.
De mon Activité, en cliquant sur l'un des éléments apporte la nouvelle instance de la même Activité, ce qui est bien. Alors j'ai appuyer sur le bouton de retour et je suis pour revenir à la première Activité. Mais en cliquant sur l'un de ces éléments (à lancer une nouvelle instance de la même Activité) provoque l'erreur suivante:
java.lang.NullPointerException: Tentative d'invoquer la méthode virtuelle java.lang.Chaîne de android.contenu.Contexte.getPackageName () sur un objet null référence
Il est également important de considérer que je suis l'appel de la nouvelle instance de l'Activité (c'est à dire où les trois éléments sont), dans l'un des fragments que j'ai dans mon Activité. Donc, quand je l'appelle, j'ai quelque chose comme:
public class MyActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
ViewPager viewPager = (ViewPager) findViewById(R.id.detail_viewpager);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) findViewById(R.id.detail_tabs);
tabLayout.setTabTextColors(
ContextCompat.getColor(this, R.color.text_white_secondary),
ContextCompat.getColor(this, R.color.text_white));
tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(this, R.color.white));
tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
...
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return 3;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: return new MainFragment();
case 1: return new MyFragment();
case 2: return new MyOtherFragment();
}
return null;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.tab_main_frag).toUpperCase(l);
case 1:
return getString(R.string.tab_my_frag).toUpperCase(l);
case 2:
return getString(R.string.tab_my_other_frag).toUpperCase(l);
}
return null;
}
}
...
public static class MyFragment extends Fragment implements MyRVAdapter.OnEntryClickListener {
...
private ArrayList<ItemObj> mArrayList;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
doStuff();
...
}
private void doStuff() {
...
mArrayList = ...;
MyRVAdapter adapter = new MyRVAdapter(getActivity(), mArrayList);
adapter.setOnEntryClickListener(new MyRVAdapter.OnEntryClickListener() {
@Override
public void onEntryClick(View view, int position) {
Intent intent = new Intent(getActivity(), MyActivity.class);
intent.putExtra("INFORMATION", mArrayList.get(position));
startActivity(intent);
}
});
}
...
}
...
}
Et voici une partie de ma coutume adaptateur:
public class MyRVAdapter extends RecyclerView.Adapter<MyRVAdapter.MyViewHolder> {
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
...
MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
...
}
@Override
public void onClick(View v) {
//The user may not set a click listener for list items, in which case our listener
//will be null, so we need to check for this
if (mOnEntryClickListener != null) {
mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
}
}
}
private Context mContext;
private ArrayList<ItemObj> mArray;
public MyRVAdapter(Context context, ArrayList<ItemObj> array) {
mContext = context;
mArray = array;
}
@Override
public int getItemCount() {
return mArray.size();
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.tile_simple, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
ItemObj anItem = mArray.get(position);
...
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
private static OnEntryClickListener mOnEntryClickListener;
public interface OnEntryClickListener {
void onEntryClick(View view, int position);
}
public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
mOnEntryClickListener = onEntryClickListener;
}
}
Voici l'erreur complète:
01-23 14:07:59.083 388-388/com.mycompany.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mycompany.myapp, PID: 388
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:77)
at android.content.Intent.<init>(Intent.java:4570)
at com.mycompany.myapp.MyActivity$MyFragment$1.onEntryClick(MyActivity.java:783)
at com.mycompany.myapp.adapter.MyRVAdapter$MyViewHolder.onClick(MyRVAdapter.java:42)
at android.view.View.performClick(View.java:5197)
at android.view.View$PerformClick.run(View.java:20926)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
L'erreur de points à la première ligne: Intent intent = new Intent(getActivity(), MyActivity.class);
(à partir du fragment) d'abord, avec la ligne après (dans l'erreur) pointant vers mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
de le remplacé onClick
méthode dans la coutume adaptateur.
J'ai aussi lu des réponses similaires, mais ils n'ont pas résolu mon problème.
Edit:
En utilisant:
if (getActivity() == null) {
Log.d(LOG_TAG, "Activity context is null");
} else {
Intent intent = new Intent(getActivity(), MyActivity.class);
intent.putExtra("INFORMATION", mArrayList.get(position));
startActivity(intent);
}
dans l'intérieur de la classe (onEntryClick
) dans le fragment, j'ai trouvé que l'appel getActivity()
retourne null
.
getActivity()
est de retourner la valeur null. Où en êtes-vous de la définition de votre OnClickListener
?veuillez ajouter le code java et - pas nécessaire - le problème est dans le code
On dirait presque que vous utilisez le même Fragment, mais avec une nouvelle Activité, donc quand il va chercher la référence à l'Activité, il n'est plus là. Êtes-vous à l'aide d'un Fragment conservé par hasard, ou êtes-vous en passant une référence à un Fragment de la nouvelle instance de l'Activité? Nous allons probablement besoin de voir un peu de code pour faire sens de ce.
Ce que je pense qu'il se produise, c'est que le
OnClickListener
contient le fragment initial. Sans voir où l' OnClickListener
est définie si je ne peux pas vraiment dire pour certains.Le
OnClickListener
est appelée dans une Fragment
dans mon Activity
.
OriginalL'auteur Farbod Salamat-Zadeh | 2016-01-19
Vous devez vous connecter pour publier un commentaire.
Donc, la question est de cette ligne
Car il est statique, vous avez une seule instance de la classe au moment de l'exécution. Lorsque vous cliquez sur un élément, une deuxième instance de la même Activité est créée, et une autre instance de
mOnEntryClickListener
est créé, en écrasant la précédente. Donc, lorsque vous appuyez sur retour pour revenir à la première instance de l'Activité, vous êtes à l'aide de l'exemple demOnEntryClickListener
de la deuxième Activité, qui a été détruit.static
de monViewHolder
. J'ai aussi lu sur ce problème particulier de la statique des classes internes, et trouvé une grande réponse à propos des fuites de mémoire et statique/classes internes.pouvez-vous svp m'aider à corriger cette erreur stackoverflow.com/questions/51405397/... @MimmoGrottoli
en fait il n'y a pas de raison que vous devez supprimer
static
de votreViewholder
déclaration. UnViewholder
devrait être unstatic class
, c'est à dire: juste un conteneur de données avec des pas de comportement (méthodes). Si vous souhaitez ajouter des méthodes à uneViewholder
que vous obliger à enlever lestatic
modificateur de laclass
définition, cela signifie que chaqueViewholder
objet a maintenant une référence à l'extérieur de la classe (dans ce cas, l'adaptateur). C'est un gaspillage de stockage et de signifie que votre architecture est erronée. Just sayin'OriginalL'auteur Mimmo Grottoli
Le problème est probablement lié à votre anonyme
OnClickListener
la capture de lagetActivity()
méthode du fragment initial. Vous pouvez essayer de la mise en œuvre de laOnClickListener
sur votreMyFragment
et de voir si les changements de comportement à tous (peut ne pas être simple):Edit: C'est un hack et pas quelque chose que je recommande généralement, mais peut contourner le problème si vous êtes dans un pincement...
Prolonger la
Application
de fournir une application statique exemple:Modifier votre AndroidManifest.xml si votre application s'exécute le
MyApplication
:Puis remplacer
getActivity()
avec un appel àMyApplication.getInstance()
:Votre solution ne fonctionne pas pour moi. Cependant, je l'ai mentionné dans ma réponse que j'ai des boutons qui, lorsqu'il est cliqué, ouvrez l'Activité. Mais je suis en fait à l'aide d'un
RecyclerView
avec un adaptateur personnalisé que j'ai fait, et l'Activité s'ouvre lorsque je clique sur un élément. Le problème peut être dans la carte car quand je l'ai testé quelque chose de ce que j'avais avant avec trois boutons au lieu de la RecyclerView et l'adaptateur, il a bien fonctionné. La raison pour laquelle je ne l'ai pas mentionné avant, c'est que je suppose qu'il n'y aurait pas un problème avec la carte, donc pas compris cela aurait fait une question plus simple.J'ai mis à jour ma réponse, je ne sais pas si ça aide, mais j'ai pensé que je pourrais tout aussi bien inclure la coutume adaptateur si le problème est là.
Le problème est, en quelque sorte, là. Où avez-vous mis votre
OnEntryClickListener
?Désolé - voir ma mise à jour de la réponse (j'ai oublié de l'inclure précédemment).
OriginalL'auteur Cory Charlton
essayer d'utiliser ma solution:
dans votre MyActivity, créer une nouvelle fonction:
Ensuite modifier doStuff ():
Je ne suis pas sûr que cela peut vous aider ou pas, mais je pense qu'au moins il peut résoudre le
context
problèmeopenAnotherActivity
(non statique) à partir d'un contexte statique. Aussi, estMyApplication.getInstance()
censé être de l'autre réponse.Je pense donc que le problème est le contexte statique. Pourquoi avez-vous besoin de faire de la Titulaire de la classe statique alors qu'il peut être dans un contexte normal
OriginalL'auteur Phan Dinh Thai
Dans le oncreate de votre fragment, maintenez la référence de votre activité et de vérifier si votre activité est en état de "reprise" avant de lancer d'autres activités.
OriginalL'auteur Suhaib Roomy
Dans votre fragment de créer une variable de type de Votre Activité:
public MainActivity activity;
Ensuite utiliser la méthode sur joindre et lui assigne la vale:
Puis utilisez votre intention avec l'activité en tant que contexte:
OriginalL'auteur Armando Esparza García