我有一個Activity
,它本身有三個Fragment
s。嘗試在空對象引用上調用虛擬方法'java.lang.String android.content.Context.getPackageName()'
在其中一個片段中,有一個RecyclerView
帶有自定義適配器,並且單擊其中一個項目將轉到另一個頁面,該頁面是相同Activity
的新實例。但是,某些行爲會在我的應用程序中導致錯誤。
從我的活動中,點擊其中一個項目可以調出相同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());
來自自定義適配器中的覆蓋onClick
方法河
我也讀過類似的答案,但他們還沒有解決我的問題。
編輯:
通過使用:
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
它幾乎聽起來像您使用的是相同的Fragment,但帶有一個新的Activity,因此當它獲取Activity引用時,它不再存在。你是否在使用保留的片段,或者你是否將片段引用傳遞給活動的新實例?我們可能需要查看一些代碼才能瞭解這一點。 – NoChinDeluxe