У меня есть Activity
, который сам по себе имеет три Fragment
s.Попытка вызвать виртуальный метод 'java.lang.String android.content.Context.getPackageName()' на ссылке нулевого объекта
В одном из этих фрагментов есть RecyclerView
с пользовательским адаптером, и нажатие на один из его элементов перейдет на другую страницу, которая является новым экземпляром того же Activity
. Однако определенное поведение вызывает ошибку в моем приложении.
В моей деятельности щелчок по одному из элементов вызывает новый экземпляр той же Деятельности, что и отлично. Затем я нажимаю кнопку «Назад», и я возвращаюсь к первой операции. Но нажав на один из этих пунктов снова (для запуска нового экземпляра той же деятельности) вызывает следующее сообщение об ошибке:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
Также важно учитывать, что я называю новый экземпляр деятельности (т.е. там, где три элемента), в одном из фрагментов, которые у меня есть в моей деятельности. Так что, когда я называю его, у меня есть что-то вроде:
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);
}
});
}
...
}
...
}
А вот часть моего пользовательского адаптера:
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;
}
}
Здесь ошибка в полной мере:
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)
Ошибка указывает на первую строку: Intent intent = new Intent(getActivity(), MyActivity.class);
(из фрагмента) сначала, после строки (в ошибке), указывающей на mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
из метода overriden onClick
в пользовательской адаптете р.
Я также читал похожие ответы, но они не решили мою проблему.
Edit:
С помощью:
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);
}
во внутреннем классе (onEntryClick
) во фрагменте, я обнаружил, что вызов getActivity()
возвращается null
.
Вероятно, 'getActivity()' возвращает значение null. Где вы устанавливаете свой 'OnClickListener'? –
, пожалуйста, добавьте код java и - не обязательно - проблема в коде – piotrek1543
Похоже, вы используете тот же фрагмент, но с новым действием, поэтому, когда он идет, чтобы получить ссылку на Activity, его больше нет. Вы используете случайно сохраненный фрагмент или передаете ссылку фрагмента на новый экземпляр Activity? Вероятно, нам нужно увидеть какой-то код, чтобы понять это. – NoChinDeluxe