Android应用网络请求崩溃问题:ArrayAdapter及抽屉Fragment点击异常
解决CategoryFragment网络请求成功时的崩溃问题
嘿,我看了你遇到的情况——网络可用时点击抽屉里的CategoryFragment按钮就崩溃,无网络时反而能正常显示“无可用数据”,而且问题出在通过ArrayAdapter加载网络数据的环节。结合你贴的代码,我发现几个核心的问题点,咱们一步步来修复:
最可能的崩溃原因:未初始化集合
你只声明了ArrayList<CategoryModel> categoryModelArrayList;,但没有初始化这个集合。当网络请求成功后,你要往这个集合里解析添加数据时,就会抛出NullPointerException,这是最常见的崩溃原因。
修复方法:提前初始化集合
可以在声明时直接初始化,或者在init方法里初始化:
// 方式1:声明时初始化 ArrayList<CategoryModel> categoryModelArrayList = new ArrayList<>(); // 方式2:在init方法里初始化 private void init(View rootView) { listcategory = (ListView) rootView.findViewById(R.id.frm_category); tvNoCategory = (TextView) rootView.findViewById(R.id.tv_no_category); categoryModelArrayList = new ArrayList<>(); // 加上这行初始化代码 loadCategory(); }
完善网络请求成功后的逻辑
你贴的onOkHttpSuccess方法代码不完整,缺少数据解析和Adapter绑定的逻辑,这也是崩溃的重要原因。咱们把这部分补全,同时处理数据为空、解析出错的情况:
@Override public void onOkHttpSuccess(int requestId, int statusCode, String response) { Log.e(TAG, "onOkHttpSuccess == 1" + response); // 只处理分类列表的请求回调 if (requestId == RequestCode.CODE_DISPLAY_CATEGORY) { try { // 这里替换成你实际的JSON解析逻辑(示例用原生JSON解析) JSONObject jsonRoot = new JSONObject(response); JSONArray categoryArray = jsonRoot.getJSONArray("data"); // 假设接口返回的分类数据在data字段里 // 先清空旧数据,避免重复添加 categoryModelArrayList.clear(); // 遍历解析每个分类数据 for (int i = 0; i < categoryArray.length(); i++) { JSONObject itemObj = categoryArray.getJSONObject(i); CategoryModel model = new CategoryModel(); // 给model设置对应属性,比如model.setId(itemObj.getInt("id")); model.setTitle(itemObj.getString("title")); categoryModelArrayList.add(model); } // 初始化或刷新Adapter if (categoryAdapter == null) { // 第一次加载数据,初始化Adapter并绑定到ListView categoryAdapter = new CategoryAdapter(getActivity(), categoryModelArrayList); listcategory.setAdapter(categoryAdapter); } else { // 已有Adapter,刷新数据即可 categoryAdapter.notifyDataSetChanged(); } // 显示ListView,隐藏无数据提示 listcategory.setVisibility(View.VISIBLE); tvNoCategory.setVisibility(View.GONE); } catch (JSONException e) { e.printStackTrace(); // 解析出错,显示无数据提示 listcategory.setVisibility(View.GONE); tvNoCategory.setVisibility(View.VISIBLE); } } }
补充网络请求失败的回调
你实现了OkHttpInterface,但目前只写了成功的回调,还需要实现失败的回调方法,确保网络请求失败时也能正确显示无数据:
@Override public void onOkHttpFailure(int requestId, IOException e) { Log.e(TAG, "分类列表请求失败:" + e.getMessage()); if (requestId == RequestCode.CODE_DISPLAY_CATEGORY) { listcategory.setVisibility(View.GONE); tvNoCategory.setVisibility(View.VISIBLE); } }
检查CategoryAdapter的实现
确保你的CategoryAdapter继承自ArrayAdapter<CategoryModel>,并且getView方法没有空指针问题。示例实现如下:
public class CategoryAdapter extends ArrayAdapter<CategoryModel> { public CategoryAdapter(Context context, ArrayList<CategoryModel> categoryList) { super(context, 0, categoryList); } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { // 获取当前位置的分类模型 CategoryModel currentCategory = getItem(position); // 复用convertView,提升性能 if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_category, parent, false); } // 绑定数据到item的控件(根据你的item布局修改) TextView tvCategoryName = convertView.findViewById(R.id.tv_category_name); tvCategoryName.setText(currentCategory.getTitle()); return convertView; } }
额外注意:确保在主线程更新UI
如果你的OkHttpRequest是在子线程执行回调的,那所有更新UI的操作(比如设置Adapter、修改控件可见性)都要切换到主线程,否则会抛出CalledFromWrongThreadException。可以用以下方式包裹UI操作:
getActivity().runOnUiThread(() -> { // 在这里执行设置Adapter、修改控件可见性的代码 });
按照上面的步骤修复后,应该就能解决网络可用时的崩溃问题了。
内容的提问来源于stack exchange,提问作者Soaham saraswat
相关产品推荐
相关产品推荐

