0

View becomes null in fragment that causes null point exception in findViewById , app crashes.

https://stackoverflow.com/a/32046142/5352516

I've used this solution.

Global variable

 protected View mView;

at onCreateView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_home, container, false);

    this.mView = view;


    videoList = new ArrayList<>();

    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());


    recyclerView =mView.findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(layoutManager);
    videoAdapter = new VideoAdapter(getContext());
    recyclerView.setAdapter(videoAdapter);

    getDataFromServer(offset);

    scrollListener = new EndlessRecyclerViewScrollListener(layoutManager) {
        @Override
        public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
            loadNextDataFromApi(page);
        }
    };
    recyclerView.addOnScrollListener(scrollListener);



    return view;
}

Here null point exception comes in all findViewById as mView becomes null.

public void getDataFromServer(int offset){
    mView.findViewById(R.id.progressBar_homeFragment).setVisibility(View.VISIBLE);
    ApiService service = ApiClient.getRetrofit().create(ApiService.class);
    Call<ArrayList<VideoDataModel>> call = service.getHomeVideos(offset, Utils.getUserId(getActivity()));
    call.enqueue(new Callback<ArrayList<VideoDataModel>>() {
        @Override
        public void onResponse(Call<ArrayList<VideoDataModel>> call, Response<ArrayList<VideoDataModel>> response) {
            videoList = response.body();
         //   Log.d(TAG, "onResponse: "+videoList);
            assert videoList != null;
            generateDataList(videoList);
            mView.findViewById(R.id.progressBar_homeFragment).setVisibility(View.GONE);

        }

        @Override
        public void onFailure(Call<ArrayList<VideoDataModel>> call, Throwable t) {

            Log.d(TAG, "onFailure: "+t);
            if (mView !=  null){
                mView.findViewById(R.id.progressBar_homeFragment).setVisibility(View.GONE);
                mView.findViewById(R.id.no_connection_home).setVisibility(View.VISIBLE);
            }



        }
    });
}

I can do this to prevent it but doing this many times is not a good practice as I feel,

    if (mView !=null){
        mView.findViewById(R.id.progressBar_homeFragment).setVisibility(View.GONE);
    }

Need your help to get out of this crash. Because of this I'm getting around 4% crash rate in my app having around 8k DAU

Pradeep Behera
  • 475
  • 6
  • 15

1 Answers1

0

First of all, the way you are using findViewById is wrong, better to take one variable for progressBar and no_connection.

Secondly, it seems like you are calling the api just before you go back from the fragment. So your fragment is removed/detached from the activity and that might be the reason you are getting null pointer exception.

So you have two options either you can cancel the enqueued network call request using call.cancel() or you can add simply null check in onResponse() method

Himanshu Dudhat
  • 1,609
  • 3
  • 14
  • 27