为什么回收视图适配器有时在视图寻呼机片段上为空



>我仍然无法复制确切的步骤,但是托管在ViewPager片段上的RecycleView适配器有时为空。

崩溃发生在安卓 8 或更高版本上。我尝试在没有后台进程或开发人员选项上"不检查活动"的情况下运行它,以防万一它受到配置更改的影响,但我没有崩溃。

回收查看片段上的适配器设置

public class FragmentExploreEvents extends InFragment implements IFragmentExploreEvents {
private String TAG = FragmentExploreEvents.class.getSimpleName();
private RecyclerView mRecyclerView;
private GenericAdapter mAdapter;
protected List<GenericBean> mData;
Calendar dateToday = DateUtils.getCalendarToday();
Calendar selectedDate = Calendar.getInstance();

// initializing the RecyclerView and Adapter
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_explore_events, container, false);
mProgressBar = view.findViewById(R.id.progress_bar);
mRecyclerView = view.findViewById(R.id.rv_content);

mData = new ArrayList<>();
LinearLayoutManager mLayoutManager = new LinearLayoutManager(mActivity, RecyclerView.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new GenericAdapter(mActivity, mData, this, true);
mRecyclerView.setAdapter(mAdapter);

return view;
}

// method that I am calling on activity to refresh the recyclerview data
@Override
public void onLoadList(List<GenericBean> data) {
if (mAdapter != null) {
// Null pointer exception is occurring on this method 
mAdapter.addData(data);
} else {
Crashlytics.log("Adapter was null");
}
}

}

承载视图寻呼机的活动

public class ExploreClassesActivity extends NewBasicDisplayActivity implements BookingCallBackListener, CustomViewPagerListener {
WeekDaysSelector weekDaysSelector;
CustomViewPager mPager;
private MyPagerAdapter mPagerAdapter;
List<GenericBean> mData = new ArrayList<>();
private int prevPagePosition = 0;
private boolean enableUpdatePageOnSwipe = false;
Calendar dateToday;
Calendar selectedDate;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe_explore_events);
weekDaysSelector = findViewById(R.id.activity_explore_event_day_selector);
mPager = findViewById(R.id.view_pager);
mToolbar = findViewById(R.id.toolbar);
setupViewPager();
setupView();
}

// setting up view pager with a listener to call loadData on page selection change
private void setupViewPager() {
mPagerAdapter =
new MyPagerAdapter(getSupportFragmentManager());
mPager.setOffscreenPageLimit(6);
mPager.setAdapter(mPagerAdapter);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
selectedDate.add(Calendar.DAY_OF_MONTH,1);
position = weekDaysSelector.highlightDate(selectedDate);
prevPagePosition = position;
loadData();
}

});
}
}
//setting up a day selection listener to load data into the current viewpager fragment
protected void setupView() {

weekDaysSelector.setListener(new WeekDaySelectorListener() {
@Override
public void onDateSelection(Calendar date, int position) {
selectedDate = date;
prevPagePosition = position;
loadData();
}

});
loadData();
}


// updating the fragment with the current fragment with the received data
private void updateFragmentList(List<GenericBean> mData) {
mPager.setCurrentItem(prevPagePosition);
// onLoadList is called on the current display view pager fragment
IFragmentExploreEvents fragmentList = (IFragmentExploreEvents) mPagerAdapter.getItem(mPager.getCurrentItem());
fragmentList.onLoadList(mData); // Null pointer is occurring 

protected void loadData() {
String fromDate = DateUtils.getStringDateFromDate(selectedDate.getTime());
selectedDate.set(Calendar.HOUR_OF_DAY, 23);
String toDate = DateUtils.getStringDateFromDate(selectedDate.getTime());
getClasses(fromDate, toDate);
}

private void getClasses(String startDate, String endDate) {
// preparing displayed fragment before calling onLoadList when api data is received
mPager.setCurrentItem(prevPagePosition);
IFragmentExploreEvents fragmentList = (IFragmentExploreEvents) mPagerAdapter.getItem(mPager.getCurrentItem());
fragmentList.onUpdate(selectedDate);
API.getOnlineClasses(InPrefs.getToken(this), startDate, endDate, new Response.Listener<ClassesResponseBean>() {
@Override
public void onResponse(ClassesResponseBean response) {
if (CodeUtils.isValidResponse(response)) {
List<GenericBean> classes = response.getClassesByHour();
updateFragmentList(classes);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
handleError(error);
updateFragmentList(new ArrayList<GenericBean>());
}
}, TAG);
}

// ViewPager adapter class extends CachingFragmentStatePagerAdapter methods to reuse viewpager 
fragments
public static class MyPagerAdapter extends CachingFragmentStatePagerAdapter {
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public int getCount() {
return DateUtils.DAYS_OF_TIME;
}
// Created fragments are reused if they were already initialized
@Override
public Fragment getItem(int position) {
if (getRegisteredFragment(position) != null) {
return getRegisteredFragment(position);
}
return FragmentExploreEvents.newInstance();
}

}

}

兑现片段状态寻呼适配器

public abstract class CachingFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// Sparse array to keep track of registered fragments in memory
private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public CachingFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager,FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
// Register the fragment when the item is instantiated
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregistered when the item is inactive
@Override
public void destroyItem(@NonNull ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}

我有时收到的空指针堆栈跟踪

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.codefish.in.adapters.GenericAdapter.addData(java.util.List)' on a null object reference
at com.codefish.in.fragments.FragmentExploreEvents.onLoadList + 2(FragmentExploreEvents.java:2)
at com.codefish.in.activities.ExploreClassesActivity.updateFragmentList + 21(ExploreClassesActivity.java:21)
at com.codefish.in.activities.ExploreClassesActivity.access$300(ExploreClassesActivity.java)
at com.codefish.in.activities.ExploreClassesActivity$3.onResponse + 69(ExploreClassesActivity.java:69)
at com.codefish.in.activities.ExploreClassesActivity$3.onResponse + 2(ExploreClassesActivity.java:2)
at com.codefish.in.api.InPostRequest.deliverResponse + 2(InPostRequest.java:2)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run + 30(ExecutorDelivery.java:30)
at android.os.Handler.handleCallback + 883(Handler.java:883)
at android.os.Handler.dispatchMessage + 100(Handler.java:100)
at android.os.Looper.loop + 237(Looper.java:237)
at android.app.ActivityThread.main + 7762(ActivityThread.java:7762)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run + 493(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main + 1047(ZygoteInit.java:1047)

您应该在onCreateView之后调用的onViewCreated上初始化适配器和回收器视图。通过这样做,您可以确保视图已经膨胀,并且可以安全地设置适配器。

最新更新