从Fragment向另一个Activity传文本时遇NullPointerException求助
解决Fragment向Activity传值时的NullPointerException问题
我看了你遇到的问题——在Fragment中点击ListView选项执行SQL查询,然后把结果传到另一个Activity时出现了NullPointerException,这大概率是代码里的实例化逻辑出问题了,咱们一步步梳理清楚:
先贴出你的Fragment代码方便对照:
public class TouristPlace extends Fragment implements AdapterView.OnItemClickListener { public ListView list; public ArrayAdapter<String> arrayAdapter; public ResultSet result; public Statement statement; public String Desc; public String output; public TouristPlace touristPlace; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.tourists, container, false); list = (ListView)rootView.findViewById(R.id.places); touristPlace=new TouristPlace(); // 这里是核心问题点! try { Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Welcome_to_hyd", "root", "test"); statement = con.createStatement(); } catch (Exception e) { System.out.println(e.getMessage()); } final String[] placelist = getResources().getStringArray(R.array.menu); arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, placelist); list.setAdapter(arrayAdapter); list.setOnItemClickListener(this); return rootView; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch(position) { case 0: output=touristPlace.result("Golconda"); // 调用未初始化实例的方法,必然空指针 Intent i = new Intent(getActivity(), ListNavigation.class); i.putExtra("DatabaseOutput", output); // 补全你原本没写完的传值逻辑 startActivity(i); break; // 其他case逻辑... } } // 假设你的result方法实现大致如下 public String result(String placeName) { String resultStr = ""; try { ResultSet rs = statement.executeQuery("SELECT description FROM places WHERE name = '" + placeName + "'"); if(rs.next()){ resultStr = rs.getString("description"); } } catch (SQLException e) { e.printStackTrace(); } return resultStr; } }
问题根源分析
你在onCreateView里手动new了一个全新的TouristPlace实例touristPlace,这个实例完全没有经过Fragment的生命周期初始化——它的statement成员变量是null,也没有绑定任何View。当你调用touristPlace.result("Golconda")时,执行statement.executeQuery必然会抛出NullPointerException。
解决方案
- 移除冗余的Fragment实例
删掉public TouristPlace touristPlace;和touristPlace=new TouristPlace();这两行代码,直接调用当前Fragment实例的result方法:
output = result("Golconda");
- 优化数据库连接管理
直接在Fragment里初始化数据库连接不是最佳实践,容易造成资源泄漏,建议把数据库操作封装成单例帮助类,或者至少在Fragment销毁时关闭连接:
// 先把Connection改成成员变量 private Connection con; @Override public void onDestroyView() { super.onDestroyView(); try { if(statement != null) statement.close(); if(con != null) con.close(); } catch (SQLException e) { e.printStackTrace(); } }
- 完善Intent传值与接收逻辑
确保传值的key明确,在接收的ListNavigationActivity里做非空判断:
// ListNavigation Activity中取值 String queryResult = getIntent().getStringExtra("DatabaseOutput"); if(queryResult != null){ // 处理结果显示逻辑 } else { // 处理查询结果为空的情况 }
- 修复SQL注入风险
你当前用字符串拼接SQL的方式存在注入风险,改用PreparedStatement更安全:
public String result(String placeName) { String resultStr = ""; try { String sql = "SELECT description FROM places WHERE name = ?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, placeName); ResultSet rs = pstmt.executeQuery(); if(rs.next()){ resultStr = rs.getString("description"); } // 及时关闭资源 rs.close(); pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } return resultStr; }
按照这些步骤修改后,NullPointerException的问题应该就能解决,同时代码的健壮性和安全性也会提升不少。
内容的提问来源于stack exchange,提问作者Satish Rongala
相关产品推荐
相关产品推荐

