将JSON响应写入文本视图

时间:2015-05-26 08:28:31

标签: android json httpresponse

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

我在AsyncTask下运行此代码。

  • url API的GET网址。
  • credentials是身份验证凭据。这是一个字符串。
  • response是文字视图。
  • getmessage是一个字符串变量。
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会将响应返回到行尾。现在我只得到了JSON响应的一部分,"未经过身份验证:",但我需要整个响应。

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

如果我的代码中有任何异常。请告诉我。

4 个答案:

答案 0 :(得分:1)

我建议你去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,以便在onPostExecute内覆盖AsyncTaskresult作为参数,来自{{1} }。如果你注意到..

doInBackground

此处private class GetDataFromUrl extends AsyncTask<URL, Integer, String> 是我们传递给URL的{​​{1}}

的类型

AsyncTask是我们从doInBackground传递到String

的内容

doInBackground用于显示您可以覆盖的另一种方法的进度,即onPostExecute ..您可以在上面提到的文档中阅读更多内容。希望它有所帮助。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

试试这个:

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

<强> EDITED

在您的代码中:

getmessage = buf.readLine();
变量getmessage中的

只读取JSON的第一行。您需要读取所有行并将其连接起来。如何知道你是否读过所有行?

以下是documentation对此的说法:

  

public String readLine()                   抛出IOException

     

<强>返回:

     

包含该行内容的字符串,不包括任何内容   行终止字符,或null 如果流已结束   达到

正如您所看到的,您应该调用此方法,将结果保存到变量中,并检查,如果变量非空,则您具有JSON的读取行。如果变量是 null ,那么您已将所有JSON读入变量,并且您已完全使用JSON字符串。

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

答案 3 :(得分:0)

如果我理解正确,你会尝试逐行读取所有响应数据。你能试试以下吗?

@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);
}

希望这有帮助。