我用Java编写了一个应用程序,我现在尝试移植到Android,但出于某种原因,当使用BufferedReader中的readLine()方法时,它返回null。我已经在Java中测试了代码,它工作正常没问题。我正在读取的文件是一个纯文本文件,我已将其余的java文件放入其中。我的代码简单地接受用户输入以进行登录,并且在单击登录按钮时通过读入包含配置文件的文本文件来检查详细信息。下面是我的代码的简化:
主要活动中的OnClickListener:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText textUsername = (EditText) findViewById(R.id.textUsername);
EditText textPassword = (EditText) findViewById(R.id.textPassword);
// Collect the login details entered by the user
String username = textUsername.getText().toString();
String password = textPassword.getText().toString();
// Check if login details are correct
LoginModel login = new LoginModel();
Correct = login.isCorrect(username, password); // LINE COMMENTED
// OUT SO THAT DETAILS DON'T NEED TO BE ENTERED
// Correct = true; // used to bypass login for now
if (Correct) { // if details are correct then start main program
Intent intent = new Intent (LoginView.this, MenuListView.class);
startActivity(intent);
}
else System.out.println("Login is incorrect...");
}
});
}
LoginModel.java类:
public LoginModel() {
file = new File("Profiles");
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Login Constructor successful!");
}
// Checks whether the inputted details are correct
public static boolean isCorrect(String u, String p) {
System.out.println(p);
boolean check = false;
String line = null;
try {
do {
line = br.readLine(); // This line is returning null
// System.out.println("Checking profile : " + line);
String[] info = line.split("\t");
// nested if-statement to improve efficiency over &&
if (info[0].equals(u)) {
System.out.println("username found!");
if (info[1].equals(p)) {
System.out.println("password correct!");
check = true;
} else
System.out.println("password incorrect!");
} else
System.out.println("username not found!");
} while (line != null && check == false);
return check;
由于某种原因返回null的是br.readLine()。我查了一下,bufferedreader似乎完全支持。
编辑:好的,我发现它实际上并没有找到该文件,但可能正在尝试执行isCorrect()方法,因为它是静态的。我现在已经删除了方法和br声明静态标记,并将配置文件文本文件移动到包含所有java文件的文件夹中,但它仍然无法找到它。我该如何参考这个职位?如果我只是按名称引用文件,那么android查找文件的默认位置是什么?非常感谢!
答案 0 :(得分:0)
我不确定这是否是NPE的实际原因,但它绝对是一个错误:
您正在构造函数中初始化br
,但您在isCorrect()
中使用它是静态的!它不需要调用LoginModel
的封闭类,因此在使用br
之前可能根本不会调用c'tor。
您应该在声明它时或在静态范围内初始化br
,以便在类加载时初始化它。
编辑:请注意,它还表示br
已声明为静态 - 因此LogicModel
的所有实例实际上都使用br
的同一对象!
br.readLine()
返回null的原因可能是您在isCorrect()
的其他调用或其他使用br
的方法中已经耗尽了该文件,但是不可能没有更多代码就知道这一点。
答案 1 :(得分:0)
你确定没有捕获到FileNotFoundException吗?这意味着Android无法找到该文件,因此无法创建BufferedReader,从而将其保留为null。通过进程在logcat中搜索FileNotFoundException(通常为橙色)或使用断点进行调试。
编辑: 在android中使用文件时,通常会将它们放在res / raw文件夹中。这是因为android没有文件的主要起点。事实上,android更喜欢限制对文件的访问(因为逻辑安全问题)。
所以你需要做的是:
将文件放在res / raw文件夹中并将其重命名为“profiles” (Android不允许在资源中使用大写字母)(也许你必须这样做 首先创建文件夹)。
编辑构造函数以接收 资源(将其更改为:“public LoginModel(Resources res)”)
相应地编辑初始化(更改“LoginModel login = new LoginModel();“to”LoginModel login = new LoginModel(getResources());“)
然后更改“br = new BufferedReader(new FileReader(file));”到“br = 新的BufferedReader(新的 InputStreamReader的(res.openRawResources(R.raw.profiles)));“
删除行“file = new File(”Profiles“);”