片段更改崩溃
Posted
技术标签:
【中文标题】片段更改崩溃【英文标题】:Crash on Fragment Change 【发布时间】:2019-02-20 19:12:28 【问题描述】:这是我的片段之一的代码 sn-p:
@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 请求时切换到另一个片段时(基本上是在片段从服务器加载数据时),应用程序崩溃,给我以下错误:
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 的上下文(因此在通过菜单时它基本上永远不会为空)?
【问题讨论】:
我相信 getView() 是空的 【参考方案1】:堆栈跟踪的第一行告诉你getView()
正在返回null
,我想你已经知道了。堆栈跟踪的第二行是它的“原因”,它只是告诉您该调用来自“哪里”:请求的响应侦听器。
这里发生的事情的根本原因是离开您的 Fragment 的导航导致 Android 框架破坏了您的 Fragment。该过程的一部分是您的 Fragment 的 onDestroyView()
方法将被调用,之后 getView()
将返回 null
。
要修复崩溃,您可以执行以下两项操作之一。
最简单的方法是将您的电话转入if (getView() != null)
。这将暂时解决问题,但这是一种快速而肮脏的事情。
更好的解决方案是利用 Android 框架调用 Fragment 的 onDestroyView()
来取消 Volley 请求。这样(a)您的应用程序不会在它不会使用的网络调用上做无用的工作,并且(b)您不必担心是否会在其中添加一些其他容易崩溃的代码未来。
可能最简单的做法是在 Fragment 的类级别(在 setListViewData()
方法之外)声明 JsonArrayRequest jsonArrayRequest
变量,然后在 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();
【讨论】:
那是要走的。我使用此代码并尝试在解析 jsonArray 时启用 Button,并且我得到另一个“NullPointerException:尝试在空对象引用上调用虚拟方法 'void android.widget.Button.setClickable(boolean)'”。如果 !=null ,我是否必须检查与 jsonArray 请求相关的每个操作? 看看我的编辑,我说的是“按钮编辑” 您确定要拨打getActivity().findViewById()
吗?这将在活动的布局中查找按钮,但我假设您想在片段的布局中找到它。请改用getView().findViewById()
。
不,是 getResources() 导致错误,我在 onCreateView 之外的类中调用它。
java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'android.content.res.Resources android.view.View.getResources()'【参考方案2】:
替换这一行:
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.
【讨论】:
是的,但是...我不能将 setListViewData() 放在返回视图之后。所以我真的不明白你的暗示!无论如何谢谢!【参考方案3】:关注这个 github repo 以帮助您在片段之间导航 https://github.com/SWAQ-COMMUNITY/SliderModule.git 然后我认为你需要在你的 res 文件夹中做一些调整,检查你是否有类似 drawable-v21 或类似文件夹的东西,将内容移动到像这样 drawable 的文件夹
例如移动drawable-v21中的所有内容>drawable
并对 mimap 和 value 应用相同的内容。然后删除那些文件夹...
此文件夹 drawable-v21 和类似 无效并重新启动,那么你应该没问题
【讨论】:
以上是关于片段更改崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio - 在片段之间更改时底部导航崩溃
每当我尝试从 Fragment java 文件中更改片段的某些属性时,应用程序就会崩溃