带有 bufferedreader.readLine () 的缓冲区意外返回 null



当我使用BufferedReader时遇到问题readLine ()它返回空值。这是我的代码:

如何发现问题的根源?

BackgroundTask_GET.java

public class BackgroundTask_GET extends AsyncTask<Void, Void, Void> {
String duongdan = MainActivity.SERVER_NAME;
TextView tvResult;
String strName, strScore;
String str;
ProgressDialog pDialog;
Context context;
public String TAG = "GG";
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(context);
pDialog.setMessage("Sending...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
public BackgroundTask_GET(Context context, TextView tvResult, String 
strName, String strScore) {
this.tvResult = tvResult;
this.strName = strName;
this.strScore = strScore;
this.context = context;
}
@Override
protected Void doInBackground(Void... voids) {
duongdan += "?name=" + this.strName + "&score=" + this.strScore;
try {
URL url = new URL(duongdan);
HttpURLConnection urlConnection = (HttpURLConnection) 
url.openConnection();
BufferedReader bfr = new BufferedReader(new 
InputStreamReader(url.openStream()));
String line = "";
StringBuffer sb = new StringBuffer();
Log.d(TAG, "bfr:" + urlConnection);
while ((line = bfr.readLine()) != null) {
sb.append(line);
Log.d(TAG, "append"+sb.append(line));
}
str = sb.toString();
urlConnection.disconnect();
Log.d(TAG, "doInBackground: " + str);
} catch (MalformedURLException e) {
e.printStackTrace();
Log.d(TAG, "exception " + e);
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "exception " + e);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (pDialog.isShowing()) {
pDialog.dismiss();
}
tvResult.setText(str);
Log.d("RESULT", "khanh" + str);
}

}

'' '主要活动

public class MainActivity extends AppCompatActivity implements 
View.OnClickListener {
public static final String SERVER_NAME = 
"http://192.168.1.2/AndroidNetworking_server/student_GET.php";
private EditText edtName, edtScore;
private Button btnSend;
private TextView tvResult;
String strName, strScore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtName = findViewById(R.id.edtName);
edtScore = findViewById(R.id.edtScore);
btnSend = findViewById(R.id.btnSend);
tvResult = findViewById(R.id.tvResult);
btnSend.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.btnSend:
strName = edtName.getText().toString();
strScore = edtScore.getText().toString();
BackgroundTask_GET backgroundTask = new 
BackgroundTask_GET(this, tvResult, strName, strScore);
backgroundTask.execute();
break;
}
}
}

错误: ~

` 1 `2019-07-15 14:07:58.065 24764- 28936/com.example.lab2_khanhpd02377_androidnetworkingD/GG:bfr:com.android.okhttp.internal.huc.HttpURLConnectionImpl:http://192.168.1.2/AndroidNetworking_server/student_GET.php?name=4&score=5 ~

` 2 `2019-07-15 14:07:58.066 24764- 28936/com.example.lab2_khanhpd02377_androidnetworking D/GG: doInBackground:

我可以看到你的代码有几个问题:

  1. readLine()方法返回删除了行分隔符的行。 所以

    while ((line = bfr.readLine()) != null) {
    sb.append(line);
    }
    

    将在读取时去除行分隔符。

  2. 您没有检查 HTTP 响应代码。 如果响应代码不是 2xx 代码,则getInputStream()将引发异常。

    可以使用getResponseCode()找到响应代码。可以使用getErrorStream()读取错误响应正文。

  3. 正如@user207421所说,除非你真的需要断开连接,否则你不应该打电话给urlConnection.disconnect()。 如果不需要,最好让 HTTP 客户端库处理断开连接。 (它也许能够保持连接打开,并将其用于以后对同一服务器的请求。

  4. 您应该 1关闭BufferedReader,理想情况下,您应该使用试用资源来执行此操作。


1 - 我不会说必须,因为在某些情况下这无关紧要。 但是,如果您不以某种方式关闭流,您将泄漏文件描述符,这可能会导致以后的错误。 而且,关闭流当然是一种很好的做法......因为你永远不知道你的代码将来是否会在资源泄漏确实很重要的上下文中使用/重用。


更新- 我想你是说null/空流的真正原因是在 PHP 方面。 尽管如此,您可能应该解决我提到的四个问题:行分隔符、响应代码、断开连接和使用 try-with-resource。

最新更新