使用ArrayAdapter展示JSON数组数据到GridView时遇空指针异常求助
解决ArrayAdapter空指针异常的问题
这个java.lang.NullPointerException很明显是因为你调用emojiAdapter.add(toAdd)时,emojiAdapter对象没有被初始化,另外你的EmojiAdapter本身的实现也存在几个关键漏洞,导致后续还会出现其他空指针问题,我来一步步帮你修复:
问题1:emojiAdapter未实例化
在StreamActivity的回调代码里,你直接调用了emojiAdapter.add(toAdd),但在此之前你从来没有创建过EmojiAdapter的实例——也就是说emojiAdapter是null,自然无法调用它的add方法。
问题2:EmojiAdapter构造函数未初始化核心成员
你的EmojiAdapter构造函数没有初始化mContext和list这两个成员变量,而且没有接收数据源列表,这会导致:
getCount()里调用list.size()时触发空指针getView()里调用mContext.getSystemService()时触发空指针
修复后的完整代码
1. 修正EmojiAdapter.java
public class EmojiAdapter extends ArrayAdapter<EmojiModel> { private Context mContext; Typeface typeface; ArrayList<EmojiModel> list; // 修正构造函数,接收数据源列表并初始化成员变量 public EmojiAdapter(@NonNull Context context, int resource, ArrayList<EmojiModel> emojiList) { super(context, resource, emojiList); this.mContext = context; this.list = emojiList; } @Override public int getCount() { // 增加空判断,避免list为null时崩溃 return list != null ? list.size() : 0; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { // 优化View复用逻辑,避免每次都重新inflate布局 if (convertView == null) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // 注意第三个参数传parent,让布局适配GridView的布局参数 convertView = inflater.inflate(R.layout.smiles_items_layout, parent, false); } ImageView imageView = convertView.findViewById(R.id.smile_image_view); // 增加边界判断,防止数组越界 if (list != null && position < list.size()) { imageView.setImageResource(Integer.parseInt(list.get(position).getEmojiFile())); } return convertView; } }
2. 修正StreamActivity.java中的代码
// 在Activity的初始化阶段(比如onCreate方法里)先创建数据源和Adapter,并绑定到GridView @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); // 替换成你的布局id // 1. 初始化数据源列表 ArrayList<EmojiModel> emojiList = new ArrayList<>(); // 2. 创建Adapter实例,传入上下文、item布局、数据源 EmojiAdapter emojiAdapter = new EmojiAdapter(this, R.layout.smiles_items_layout, emojiList); // 3. 绑定到GridView GridView emojiGridView = findViewById(R.id.your_gridview_id); // 替换成你的GridView的id emojiGridView.setAdapter(emojiAdapter); // 4. 订阅回调处理数据 Communicator.getInstance().on("subscribe start", new Emitter.Listener() { @Override public void call(Object... args) { try{ JSONDictionary response = (JSONDictionary) args[0]; String str = response.get("emojiPack").toString(); JSONArray emojies = new JSONArray(str); // 先清空旧数据(如果需要的话) emojiList.clear(); for(int i=0;i<emojies.length();i++) { JSONObject response2 = emojies.getJSONObject(i); EmojiModel toAdd = new EmojiModel((String) response2.get("urlFile")); JSONDictionary t = JSONDictionary.fromString(response2.toString()); toAdd.init(t); // 将数据添加到数据源列表 emojiList.add(toAdd); } // 通知Adapter数据已更新,GridView会自动刷新 emojiAdapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); } } }); }
关键修复点说明
- 初始化Adapter:必须先创建
EmojiAdapter的实例并绑定到GridView,才能在回调中使用它 - 构造函数优化:让Adapter接收数据源列表,同时初始化
mContext和list,避免后续空指针 - 数据更新方式:直接操作数据源列表,然后调用
notifyDataSetChanged(),比逐个调用add()更高效,也符合ArrayAdapter的设计逻辑 - 空判断与边界检查:增加多处空判断和位置边界检查,避免潜在的崩溃
- View复用:优化
getView()的复用逻辑,提升GridView的滚动性能
内容的提问来源于stack exchange,提问作者Omar Salah
相关产品推荐
相关产品推荐

