You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:03:38