片段更改崩溃

时间:2018-09-16 20:06:01

标签: android android-fragments

这是我的一个片段的代码片段:

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

    View view = inflater.inflate(R.layout.fragment_three, container, false);

 listView = (ListView)view.findViewById(R.id.list_listview);
        adapter=new list_adapter(getActivity(),transaction_list);
        transaction_list.clear();
        listView.setAdapter(adapter);
        setListViewData();
return view;

}

private void setListViewData() {

        RequestQueue requestQueue = Volley.newRequestQueue(getContext());
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, listurl, null,
                new Response.Listener<JSONArray>() {
            public void onResponse(JSONArray jsonArray) {
                if (jsonArray.length() > 0) {
                    Log.e("JSON ARRAY", jsonArray.toString());


                    for (int i = 0; i < jsonArray.length(); i++) {
                        try {

                            JSONObject obj = jsonArray.getJSONObject(i);
                            User user = new User();

                            User.setmName(obj.getString("name"));
                            User.setmnName(obj.getString("nname"));
                            User.setmDate(obj.getString("date"));
                            User.setmProfile(obj.getString("profile"));
                            user.setmDirection(obj.getString("direction"));


                            transaction_list.add(user);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        adapter.notifyDataSetChanged();
                    }
                    try {
                        info.setText(getView().getResources().getString(R.string.user_rest, jsonArray.getJSONObject(0).getString("info")));

            Button edit = getActivity().findViewById(R.id.button_edit);
            edit.setClickable(true);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }


            }


        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.e("Error", String.valueOf(volleyError));
            }
        });

        // add json array request to the request queue
        requestQueue.add(jsonArrayRequest);


    }
}

该代码运行良好,但是当我在处理Volley Request时切换到另一个片段时(基本上是在该片段从服务器加载数据时),应用崩溃了,给了我以下错误:

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“ android.content.res.Resources android.view.View.getResources()”     .onResponse(fragment_three.java:178)     .onResponse(fragment_three.java:151)

第178行: info.setText(getView()。getResources()。getString(R.string.user_rest,jsonArray.getJSONObject(0).getString(“ info”))))

第151行: 新的Response.Listener(){

第178行中的错误在某种程度上清楚了为什么会发生,但是如何防止它发生呢?

第151行的错误有点奇怪,可能是因为当我切换到另一个片段时,在“ Volley.newRequestQueue(getContext());”之前的行中的getContext()为“ null”还是这包含所有片段的Main Activity的上下文(因此在浏览菜单时基本上从不为null)?

3 个答案:

答案 0 :(得分:0)

堆栈跟踪的第一行告诉您getView()返回null,我想您已经知道了。堆栈跟踪的第二行是其“原因”,它只是告诉您调用的“位置”:请求的响应侦听器。

发生这种情况的根本原因是,离开Fragment的导航导致Android框架破坏了Fragment。该过程的一部分是,将调用您片段的onDestroyView()方法,此后getView()将返回null

要解决崩溃问题,您可以执行以下两项操作之一。

最简单的方法就是将您的通话包裹在if (getView() != null)中。暂时可以解决此问题,但这是一种快速而肮脏的事情。

更好的解决方案是利用Android框架调用您的Fragment的onDestroyView()来取消您的Volley请求的事实。这样,(a)您的应用程序将不会在不使用的网络调用上执行无用的工作,并且(b)您不必担心是否会在其中添加其他容易崩溃的代码未来。

可能最简单的方法是在Fragment的类级别(在JsonArrayRequest jsonArrayRequest方法之外)声明setListViewData()变量,然后在onDestroyView()中清除它:

JsonArrayRequest jsonArrayRequest;

private void setListViewData() {
    RequestQueue requestQueue = Volley.newRequestQueue(getContext());
    jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, listurl, null,
            new Response.Listener<JSONArray>() {
                ...
            });
}

@Override
public void onDestroyView() {
    if (jsonArrayRequest != null) {
        jsonArrayRequest.cancel();
    }
}

答案 1 :(得分:0)

替换此行:

info.setText(getView().getResources().getString(R.string.user_rest, jsonArray.getJSONObject(0).getString("info")));

具有:

info.setText(getActivity().getResources().getString(R.string.user_rest, jsonArray.getJSONObject(0).getString("info")));

注意:

 setListViewData(); //call function(getView()) before really get view.
 return view;//only after this line the view returnd.

答案 2 :(得分:-1)

关注此github存储库以帮助您在片段之间导航 https://github.com/SWAQ-COMMUNITY/SliderModule.git 然后我认为您需要在res文件夹中进行一些调整,检查是否有类似 drawable-v21 或类似文件夹的内容,将内容移动到类似此drawable的文件夹中

  

例如将所有内容移动到drawable-v21> drawable

,并将其应用于mimap和value。然后删除这些文件夹...

  

此文件夹drawable-v21和类似文件夹    无效并重新启动,那么您应该没事