Android中Toast因null不显示的问题排查与解决求助
问题:点击按钮后Toast无法显示,房产价格无法加载
程序在模拟器中可正常启动且无崩溃,但点击四个按钮中的任意一个,本该从listings.csv获取对应房产价格并显示Toast,现在毫无反应。尝试过通过ID判断按钮(例如id == R.id.button3),但始终无法满足property != null的条件,模拟器通知已开启。
相关代码
MainActivity.java
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity implements View.OnClickListener { private Listing listing; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listing = new Listing(); listing.loadProperties("listings.csv"); Button button3 = findViewById(R.id.button3); Button button4 = findViewById(R.id.button4); Button button5 = findViewById(R.id.button5); Button button6 = findViewById(R.id.button6); button3.setOnClickListener(this); button4.setOnClickListener(this); button5.setOnClickListener(this); button6.setOnClickListener(this); } @Override public void onClick(View view) { Button clickedButton = (Button) view; String location = clickedButton.getText().toString(); Property property = listing.getProperty(location); if (property != null) { String priceText = "Price: $" + property.getPrice(); Toast.makeText(this, priceText, Toast.LENGTH_SHORT).show(); } } }
Property.java
public abstract class Property { private String ID; private String location; private double price; public Property(String ID, String location, double price) { this.ID = ID; this.location = location; this.price = price; } public String getID() { return ID; } public void setID(String ID) { this.ID = ID; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "ID: " + ID + "\nLocation: " + location + "\nPrice: " + price; } }
CommercialProperty.java
public class CommercialProperty extends Property { private String zone; private int numUnits; private int numParkingSpots; public CommercialProperty(String ID, String location, double price, String zone, int numUnits, int numParkingSpots) { super(ID, location, price); this.zone = zone; this.numUnits = numUnits; this.numParkingSpots = numParkingSpots; } public String getZone() { return zone; } public void setZone(String zone) { this.zone = zone; } public int getNumUnits() { return numUnits; } public void setNumUnits(int numUnits) { this.numUnits = numUnits; } public int getNumParkingSpots() { return numParkingSpots; } public void setNumParkingSpots(int numParkingSpots) { this.numParkingSpots = numParkingSpots; } @Override public String toString() { return super.toString() + "\nZone: " + zone + "\nUnits: " + numUnits + "\nParking Spots: " + numParkingSpots; } }
ResidentialProperty.java
public class ResidentialProperty extends Property { private double annualHoaFees; private int numBedrooms; private double numBathrooms; public ResidentialProperty(String ID, String location, double price, double annualHoaFees, int numBedrooms, double numBathrooms) { super(ID, location, price); this.annualHoaFees = annualHoaFees; this.numBedrooms = numBedrooms; this.numBathrooms = numBathrooms; } public double getAnnualHoaFees() { return annualHoaFees; } public void setAnnualHoaFees(double annualHoaFees) { this.annualHoaFees = annualHoaFees; } public int getNumBedrooms() { return numBedrooms; } public void setNumBedrooms(int numBedrooms) { this.numBedrooms = numBedrooms; } public double getNumBathrooms() { return numBathrooms; } public void setNumBathrooms(double numBathrooms) { this.numBathrooms = numBathrooms; } @Override public String toString() { return super.toString() + "\nAnnual HOA Fees: " + annualHoaFees + "\nBedrooms: " + numBedrooms + "\nBathrooms: " + numBathrooms; } }
Listing.java
import java.util.ArrayList; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class Listing { private ArrayList<Property> properties; public Listing() { properties = new ArrayList<>(); } public void loadProperties(String fileName) { try (BufferedReader br = new BufferedReader(new FileReader("listings.csv"))) { String line; while ((line = br.readLine()) != null) { String[] data = line.split(" "); if (data.length >= 6) { String ID = data[0]; String location = data[1] + " " + data[2] + " " + data[3]; double price = Double.parseDouble(data[4]); if (ID.startsWith("rp")) { double annualHoaFees = Double.parseDouble(data[5]); int numBedrooms = Integer.parseInt(data[6]); double numBathrooms = Double.parseDouble(data[7]); ResidentialProperty rp = new ResidentialProperty(ID, location, price, annualHoaFees, numBedrooms, numBathrooms); properties.add(rp); } else if (ID.startsWith("cp")) { String zone = data[5]; int numUnits = Integer.parseInt(data[6]); int numParkingSpots = Integer.parseInt(data[7]); CommercialProperty cp = new CommercialProperty(ID, location, price, zone, numUnits, numParkingSpots); properties.add(cp); } } } } catch (IOException e) { e.printStackTrace(); } } public Property getProperty(String address) { for (Property prop : properties) { if (prop.getLocation().equals(address)) { return prop; } } return null; } }
问题根源及修复方案
1. 文件读取路径错误(核心问题)
Android应用无法直接通过new FileReader("listings.csv")读取根目录文件,必须将listings.csv放在项目的src/main/assets目录下,同时修改Listing类的文件读取逻辑:
import android.content.Context; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Listing { private ArrayList<Property> properties; private Context context; public Listing(Context context) { properties = new ArrayList<>(); this.context = context; } public void loadProperties(String fileName) { try (BufferedReader br = new BufferedReader(new InputStreamReader(context.getAssets().open(fileName)))) { String line; // 跳过CSV表头(如果有表头的话) br.readLine(); while ((line = br.readLine()) != null) { // 标准CSV用逗号分割,替换原有的空格分割 String[] data = line.split(","); // 严格判断数据长度,避免数组越界 if (data.length >= 8) { String ID = data[0].trim(); String location = data[1].trim(); double price = Double.parseDouble(data[2].trim()); if (ID.startsWith("rp")) { double annualHoaFees = Double.parseDouble(data[3].trim()); int numBedrooms = Integer.parseInt(data[4].trim()); double numBathrooms = Double.parseDouble(data[5].trim()); properties.add(new ResidentialProperty(ID, location, price, annualHoaFees, numBedrooms, numBathrooms)); } else if (ID.startsWith("cp")) { String zone = data[3].trim(); int numUnits = Integer.parseInt(data[4].trim()); int numParkingSpots = Integer.parseInt(data[5].trim()); properties.add(new CommercialProperty(ID, location, price, zone, numUnits, numParkingSpots)); } } } } catch (IOException | NumberFormatException e) { e.printStackTrace(); } } // 增加获取所有房产的方法,用于调试 public ArrayList<Property> getProperties() { return properties; } public Property getProperty(String address) { for (Property prop : properties) { if (prop.getLocation().equals(address)) { return prop; } } return null; } }
2. 修改MainActivity中Listing的初始化
// 在MainActivity的onCreate方法中 listing = new Listing(this); listing.loadProperties("listings.csv");
3. 验证按钮文本与CSV数据的一致性
确保按钮上的文本和CSV文件中location字段完全一致(包括大小写、空格),同时在onClick中增加调试逻辑,定位问题:
import android.util.Log; // 在MainActivity的onClick方法中 @Override public void onClick(View view) { Button clickedButton = (Button) view; String location = clickedButton.getText().toString(); Log.d("MainActivity", "当前点击按钮文本:" + location); Property property = listing.getProperty(location); if (property != null) { String priceText = "Price: $" + property.getPrice(); Toast.makeText(this, priceText, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "未找到对应房产", Toast.LENGTH_SHORT).show(); // 打印所有已加载的房产地址,方便对比 for (Property p : listing.getProperties()) { Log.d("MainActivity", "已加载地址:" + p.getLocation()); } } }
4. 修正CSV文件格式
使用标准CSV格式(逗号分割),示例如下:
rp001,123 Main St,500000,1200,3,2.0 cp001,456 Business Rd,1200000,Commercial,4,10
内容的提问来源于stack exchange,提问作者Burger290
相关产品推荐
相关产品推荐

