首页 > 解决方案 > getView 在 Fragment,Android 中变为 null

问题描述

View 在片段中变为空,导致 findViewById 出现空点异常,应用程序崩溃。

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

我用过这个解决方案。

全局变量

 protected View mView;

在 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;
}

当 mView 变为空时,所有 findViewById 都会出现空点异常。

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);
            }



        }
    });
}

我可以这样做来防止它,但我觉得多次这样做并不是一个好习惯,

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

需要您的帮助才能摆脱这场崩溃。因此,我的应用程序的崩溃率约为 4%,其 DAU 约为 8k

标签: android

解决方案


首先,你使用findViewById的方式是错误的,最好为progressBar和no_connection取一个变量。

其次,您似乎在从片段返回之前调用了 api。因此,您的片段已从活动中删除/分离,这可能是您收到空指针异常的原因。

因此,您有两个选择,您可以使用取消排队的网络呼叫请求call.cancel(),也可以添加简单的 null 签入onResponse()方法


推荐阅读