Android Java onCreate中无SharedPreferences时调用PopupMenu闪退如何解决
错误原因
- 变量作用域覆盖:你已经在Activity中声明了全局的
private PopupMenu popupMenu;,但在setOnClickListener的匿名内部类里又写了PopupMenu popupMenu = new PopupMenu(...),这行代码创建的是局部变量,完全没有给全局的popupMenu赋值,全局变量始终是null。 - 初始化时机错误:哪怕解决了作用域问题,popupMenu的初始化逻辑现在是写在按钮点击回调里的,onCreate执行的时候用户还没点击按钮,全局popupMenu依然是未初始化的状态,调用show自然会报空。
修复方案
- 先把popupMenu的初始化逻辑抽成独立的公共方法,避免代码冗余:
// 新增全局统一初始化PopupMenu private void initPopupMenu() { popupMenu = new PopupMenu(MainActivity.this, setlocation); try { JSONArray txturljsonarr = new JSONArray(getString(R.string.txturljson)); for (int j = 0; j < txturljsonarr.length(); ++j) { JSONObject txturljsonitem = txturljsonarr.getJSONObject(j); String menuitem = txturljsonitem.getString("menu"); popupMenu.getMenu().add(menuitem); } } catch (JSONException e) { e.printStackTrace(); } popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { try { JSONArray txturljsonarr = new JSONArray(getString(R.string.txturljson)); for (int j = 0; j < txturljsonarr.length(); ++j) { JSONObject txturljsonitem = txturljsonarr.getJSONObject(j); String menuitem = txturljsonitem.getString("menu"); String chosenitem = (String) menuItem.getTitle(); if (menuitem.equals(chosenitem)) { query_url_from_txturljson = txturljsonitem.getString("url"); title_from_txturljson = txturljsonitem.getString("title"); } } } catch (JSONException e) { e.printStackTrace(); } SharedPreferences.Editor editor = appsharedprefs.edit(); editor.putString("shpref_url", query_url_from_txturljson); editor.putString("shpref_title", title_from_txturljson); editor.apply(); makeJsonArrayRequest(); return true; } }); }
- 修改按钮点击逻辑,直接调用初始化完成的popupMenu显示即可:
setlocation = (Button) findViewById(R.id.setlocation); setlocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { popupMenu.show(); } });
- 修改onCreate里的判断逻辑,先执行初始化再判断是否需要弹出:
// 先完成popupMenu初始化 initPopupMenu(); SharedPreferences appsharedprefs = this.getSharedPreferences("appsharedprefs", MODE_PRIVATE); shpref_url = appsharedprefs.getString("shpref_url","no URL defined"); if (shpref_url.equals("no URL defined")) { popupMenu.show(); }
注意:确保
query_url_from_txturljson、title_from_txturljson、appsharedprefs这些变量已经在Activity中声明为全局变量,避免出现新的空指针异常。
内容的提问来源于stack exchange,提问作者josewe
相关产品推荐
相关产品推荐

