写 JSON 个对文本视图的响应

Write JSON response to a text view

我正在通过 REST API 验证外部系统。 http认证请求格式为Basic Authorization。响应采用 JSON 格式。

我运行这个代码下一个AsyncTask

connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", "Basic" +  Base64.encode(credentials.getBytes(), Base64.DEFAULT ));

// I am reading the response here,
InputStreamReader in = new InputStreamReader(connection.getInputStream());
buf = new BufferedReader(in);
getmessage = buf.readLine();

// After making the request, I am updating the response to a text view on the UI thread
runOnUiThread(new Runnable() {
    @Override
    public void run() {
        response.setText(getmessage);
    }
});

我无法将整个 JSON 数据写入文本视图。我知道 buf.readline returns 直到一行结束的响应。现在我只收到 JSON 响应的一部分,"Not Authenticated:",但我需要整个响应。

如何更新对文本视图 (response) 的整个 JSON 响应?如果我在循环中使用 buf.readline 循环数据,那么我可以在哪里使用它?在哪个线程中?

如果我的代码有什么异常。请告诉我。

您仅使用 readLine() 读取响应的第一行。在循环中调用它,直到读取所有行,并将每个新行附加到前一行。

试试这个:

StringBuilder sb = new StringBuilder();
while ((getmessage = buf.readLine()) != null) {
    sb.append(getmessage);
}
getmessage = sb.toString();

已编辑

在您的代码中:

getmessage = buf.readLine();

在变量 getmessage 中只读取 JSON 的第一行。您需要阅读所有行并将其连接起来。如何知道您是否阅读了所有行?

这是 documentation 对它的评价:

public String readLine() throws IOException

Returns:

A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

如你所见,你应该调用这个方法,将它的结果保存到变量中,并检查,如果变量是 not null,那么你已经读取了行 JSON。如果变量是 null,那么你已经将所有 JSON 读入变量并且你有完整的 JSON String.

StringBuilder 用于避免创建不必要的对象,阅读更多相关信息 here

如果我没理解错的话,你是想逐行读取所有响应数据。您可以尝试以下方法吗?

@Override
protected String doInBackGround(...){
    . . .
    BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream), 8 * 1024);
    String line = "";
    StringBuilder sb = new StringBuilder();
    while ((line = rd.readLine()) != null) {
        sb.append(line);
    }
    String response = sb.toString();
    return response;
}

@Override
protected void onPostExecute(String response){
    Textview tv = your_textview;
    your_textview.settext(whatever_part_you_get_from_response);
}

希望对您有所帮助。

我建议你通过 AsyncTask

private class GetDataFromUrl extends AsyncTask<URL, Integer, String> {

    protected String doInBackground(URL... urls) {

        connection = (HttpURLConnection)new URL(url).openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Authorization", "Basic" +  Base64.encode(credentials.getBytes(), Base64.DEFAULT ));

        InputStreamReader in = new InputStreamReader(connection.getInputStream());
        buf = new BufferedReader(in);
        StringBuilder sb = new StringBuilder();

        while ((getmessage = buf.readLine()) != null) {
            sb.append(getmessage);
        }

        getmessage = sb.toString();

        return getmessage;
    }

    protected void onPostExecute(String result) {

         // Result will be available here (this runs on main thread)
         // Show result in text view here.
         response.setText(result);

    }
}

为了更好地理解,当您调用 AsyncTask 时,doInBackground 在创建的新线程上运行。放置网络调用和解析数据的位置。现在,我们需要访问主线程上的数据来更新 TextView,因此覆盖 AsyncTask 中的 onPostExecuteresult 作为参数,从 doInBackground.另外如果你注意到..

private class GetDataFromUrl extends AsyncTask<URL, Integer, String> 

这里 URL 是我们传递给 AsyncTask 的类型 doInBackground

String 是我们从 doInBackground 传递给 onPostExecute

Integer 用于显示您可以覆盖的另一种方法的进度,即 onProgressUpdate .. 您可以在上面喜欢的文档中阅读更多内容。希望对您有所帮助。