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

Android中ImageView空指针、drawable转Byte[]及GridView占位实现疑问

问题解答

1. 初始报错原因

你遇到的Attempt to invoke virtual method 'void android.widget.ImageView.setBackgroundResource(int)' on a null object reference报错,本质是你只声明了ImvTempCashCard变量,没有通过findViewById绑定布局中的ImageView实例,调用空对象的方法必然触发空指针。

2. 完全不需要ImageView即可读取drawable并转byte数组

不需要用ImageView做中间载体,也不需要调用setBackgroundResource方法,直接通过系统资源API即可读取drawable资源,转换为字节数组。

3. 当前业务代码的错误点

你写的Cursor遍历逻辑存在两处明显问题:

  • 空判断逻辑错误:如果SQLite的blob字段为空,cursor.getBlob(4)会直接返回null,你直接调用CashCardImage.length会先触发空指针,而不是进入length==1的判断分支
  • 字节数组生成逻辑错误:你创建ByteArrayOutputStream后,没有将Bitmap压缩写入流,直接调用toByteArray()得到的必然是空数组

4. 修正后的业务逻辑代码

try {
    Cursor cursor = MainActivity.sqLiteHelper.getData("SELECT id,cash_card_actual_no,hh_number,series_number,cc_image, id_image, cash_card_scanned_no FROM CgList");
    list.clear();

    while (cursor.moveToNext()) {
        int id = cursor.getInt(0);
        byte[] CashCardImage = cursor.getBlob(4);
        // 补充你漏写的卡号变量赋值
        String cashCardNumber = cursor.getString(1);

        // 正确判断:blob为null或者长度为0时都使用默认图
        if (CashCardImage == null || CashCardImage.length == 0) {
            // 直接读取drawable资源为Bitmap
            Bitmap originBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(),R.drawable.ic_creditcard);
            // 按需缩放尺寸
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap, 120, 120, false);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            // 将Bitmap压缩写入输出流,格式可选PNG/JPEG,质量可按需调整
            scaledBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] defaultImageBytes = stream.toByteArray();
            CashCardImage = defaultImageBytes;
            // 回收无用Bitmap避免内存泄漏
            originBitmap.recycle();
            scaledBitmap.recycle();
            stream.close();
        }
        list.add(new Inventory(cashCardNumber, CashCardImage,id));
    }
    adapter.notifyDataSetChanged();
} catch (Exception e) {
    e.printStackTrace();
}

5. 可选优化方案

你也可以把默认图的判断逻辑放到Adapter的getView方法中,不需要在数据遍历阶段提前转字节数组,性能表现更好,修改Adapter对应代码即可:

@Override
public View getView(int position, View view, ViewGroup viewGroup) {
    // 原有ViewHolder初始化逻辑保持不变
    View row = view;
    ViewHolder holder = new ViewHolder();
    if(row == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(layout, null);
        holder.imageView = (ImageView) row.findViewById(R.id.imgFood);
        row.setTag(holder);
    } else {
        holder = (ViewHolder) row.getTag();
    }
    Inventory inventory = foodsList.get(position);
    byte[] foodImage = inventory.getImage();
    Bitmap showBitmap;
    if (foodImage == null || foodImage.length == 0) {
        // 直接读取drawable作为默认图,不需要转字节数组
        showBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_creditcard);
        showBitmap = Bitmap.createScaledBitmap(showBitmap, 120, 120, false);
    } else {
        showBitmap = BitmapFactory.decodeByteArray(foodImage, 0, foodImage.length);
    }
    holder.imageView.setImageBitmap(showBitmap);
    return row;
}

内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:15:00