使用BaseAdapter填充GridView时出现布局加载异常及空指针求助
我花了点时间梳理你的代码和堆栈信息,发现问题主要出在这几个地方:
首先,你的getView()方法里用try-catch把异常吞掉了——如果inflater.inflate()失败,view会变成null,直接返回null给AbsListView就触发了空指针崩溃,堆栈里的java.lang.NullPointerException at android.widget.AbsListView.obtainView(AbsListView.java:2474)就是最好的证明。
另外还有几个写法上的细节问题也可能导致这个错误,我给你整理了完整的修复方案:
1. 正确加载布局,不要传null给inflate方法
你现在用的inflater.inflate(R.layout.images_list, null)存在问题:第二个参数传null会导致布局无法正确继承GridView的LayoutParams,测量阶段容易出异常。应该改成:
view = inflater.inflate(R.layout.images_list, parent, false);
第三个参数false表示不要立即把布局添加到parent中,GridView会自行处理这个逻辑。
2. 移除无效的try-catch,避免返回null视图
原来的try-catch只打印异常但不处理,导致view为null时直接返回,这是崩溃的直接原因。要么去掉try-catch让异常直接暴露(方便你排查布局加载的真实问题,比如布局文件是否存在),要么在catch里给一个默认视图兜底:
catch (Exception ex) { ex.printStackTrace(); // 生成默认ImageView避免返回null view = new ImageView(context); ((ImageView)view).setImageResource(R.drawable.ic_launcher_foreground); }
3. 实现ViewHolder模式,优化性能同时规避控件查找错误
每次getView都调用findViewById不仅效率低,还可能因布局加载异常导致控件查找失败。用ViewHolder模式可以同时解决这两个问题:
修改后的完整Adapter代码:
public class adapter extends BaseAdapter { Context context; int images[]; LayoutInflater inflater; public adapter(final Context applicationcontext, final int[] images) { this.context = applicationcontext; this.images = images; // 更稳妥的LayoutInflater初始化方式 inflater = (LayoutInflater) applicationcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return images.length; } // 正确实现getItem,返回对应位置的数据 @Override public Object getItem(int position) { return images[position]; } // 正确实现getItemId,返回位置索引 @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // 复用convertView,提升列表性能 if (convertView == null) { convertView = inflater.inflate(R.layout.images_list, parent, false); holder = new ViewHolder(); holder.imageView = convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.imageView.setImageResource(images[position]); return convertView; } // ViewHolder内部类,缓存控件引用 private static class ViewHolder { ImageView imageView; } }
4. 检查布局文件和资源有效性
最后确认R.layout.images_list确实存在、R.id.icon在布局中正确定义,同时images数组里的资源id都是有效的,没有拼写错误或不存在的drawable资源。
按照上面的修改,应该就能解决这个空指针崩溃问题了~
内容的提问来源于stack exchange,提问作者Zain Arshad

