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
相关产品推荐
相关产品推荐

