So I have a problem of understanding (i think) of how refreshing UI works. I have an activity with a bottom navigation bar with 3 items that load a fragment. Each fragment load data from internet so I download these data into a thread and when it's finished I refresh my recyclerview on the UI Thread.
But the problem is when I select an item on the navigation bar and when i immediately select an other item my app crashes because the download of the data is finished and the UI thread is trying to refresh the recyclerview but i'm no longer on the fragment
So how can I manage to avoid this crash ?
Here is my code :
private void refreshRecyclerView() {
new Thread(new Runnable() {
@Override
public void run() {
predictionList = ComboBetHTMLParser.getPredictionList();
updateUI();
}
}).start();
}
private void updateUI() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
adapter = new PredictionAdapter(predictionList);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
}
EDIT :
Here is the error log :
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.runOnUiThread(java.lang.Runnable)' on a null object reference
at com.projects.morgan.kingwin.Fragments.SafeFragment.updateUI(SafeFragment.java:61)
at com.projects.morgan.kingwin.Fragments.SafeFragment.access$100(SafeFragment.java:20)
at com.projects.morgan.kingwin.Fragments.SafeFragment$1.run(SafeFragment.java:55)
at java.lang.Thread.run(Thread.java:764)
Main Activity bottom navigation bar code :
bottomNavigationBar.setTabSelectedListener(new BottomNavigationBar.OnTabSelectedListener() {
@Override
public void onTabSelected(int position) {
displayOnSelectedScreen(position);
}
@Override
public void onTabUnselected(int position) {
Log.d("TEST", "onTabUnselected:" + position);
}
@Override
public void onTabReselected(int position) {
Log.d("TEST", "onTabReselected:");
}
});
private void displayOnSelectedScreen(int position) {
// Begin the transaction
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = null;
switch (position) {
case 0:
if (accueilFragment == null) {
accueilFragment = new AccueilFragment();
}
fragment = accueilFragment;
break;
case 1:
if (predictionsFragment == null) {
predictionsFragment = new PredictionsFragment();
}
fragment = predictionsFragment;
break;
case 2:
if (safeFragment == null) {
safeFragment = new SafeFragment();
}
fragment = safeFragment;
break;
}
ft.replace(R.id.content_frame,fragment).commit();
}
Fragment code :
public class SafeFragment extends Fragment {
private List<Prediction> predictionList = new ArrayList<>();
private RecyclerView recyclerView;
private PredictionAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.recycler_view_pronos, container, false);
initRecyclerView(view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (predictionList.size() == 0) {
refreshRecyclerView();
}
}
private void initRecyclerView(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
adapter = new PredictionAdapter(predictionList);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
}
private void refreshRecyclerView() {
new Thread(new Runnable() {
@Override
public void run() {
predictionList = InternetData.getPredictionList();
updateUI();
}
}).start();
}
private void updateUI() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
adapter = new PredictionAdapter(predictionList);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
}
}