web-dev-qa-db-ja.com

HttpUrlConnection.getInputStreamはAndroid

HttpUrlConnectionを使用してサーバーにGETリクエストを行います。接続後:

  1. 応答コードを取得します:200
  2. 応答メッセージが表示されます:OK
  3. 入力ストリームを取得しますが、例外はスローされませんが、次のようになります。

    • スタンドアロンプ​​ログラムでは、予想どおり、応答の本文を取得します。

    {"name": "my name"、 "birthday": "01/01/1970"、 "id": "100002215110084"}

    • Androidアクティビティでは、ストリームが空(available()== 0)であるため、テキストを取得できません。

従うべきヒントや道はありますか?ありがとう。

編集:ここにコードがあります

注意:私はimport Java.net.HttpURLConnection;を使用しています。これは標準のhttp Javaライブラリです。他の外部ライブラリは使用したくない。実際に使用しました。 Android Apacheのライブラリhttpclientの使用に問題があります(匿名の.classの一部はapkコンパイラで使用できません)。

さて、コード:

URLConnection theConnection;
theConnection = new URL("www.example.com?query=value").openConnection(); 

theConnection.setRequestProperty("Accept-Charset", "UTF-8");

HttpURLConnection httpConn = (HttpURLConnection) theConnection;


int responseCode = httpConn.getResponseCode();
String responseMessage = httpConn.getResponseMessage();

InputStream is = null;
if (responseCode >= 400) {
    is = httpConn.getErrorStream();
} else {
    is = httpConn.getInputStream();
}


String resp = responseCode + "\n" + responseMessage + "\n>" + Util.streamToString(is) + "<\n";

return resp;

そうですか:

200
OK
応答の本文

だけ

200 OK

androidで

8
cibercitizen1

Tomislavのコードを試してみると、答えがわかります。

私の関数streamToString()は、.available()を使用して、受信したデータがあるかどうかを検知し、Androidでは0を返します。確かに、私はそれをあまりにも早く呼んだ。

むしろreadLine()を使用する場合:

class Util {
public static String streamToString(InputStream is) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }
}

次に、データが到着するのを待ちます。

ありがとう。

12
cibercitizen1

文字列で応答を返す次のコードを試すことができます。

public String ReadHttpResponse(String url){
        StringBuilder sb= new StringBuilder();
        HttpClient client= new DefaultHttpClient();     
        HttpGet httpget = new HttpGet(url);     
        try {
            HttpResponse response = client.execute(httpget);
            StatusLine sl = response.getStatusLine();
            int sc = sl.getStatusCode();
            if (sc==200)
            {
                HttpEntity ent = response.getEntity();
                InputStream inpst = ent.getContent();
                BufferedReader rd= new BufferedReader(new InputStreamReader(inpst));
                String line;
                while ((line=rd.readLine())!=null)
                {
                    sb.append(line);
                }
            }
            else
            {
                Log.e("log_tag","I didn't  get the response!");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
4
Tomislav

ストリームデータの準備ができていない可能性があるため、ストリームにアクセスする前に、ストリーム内のデータが利用可能であることをループで確認する必要があります。データの準備ができたら、データを読み取って、バイト配列などの別の場所に保存する必要があります。バイナリストリームオブジェクトは、データをバイト配列として読み取るのに適しています。バイト配列がより適切な選択である理由は、データが画像ファイルなどのようなバイナリデータである可能性があるためです。

InputStream is = httpConnection.getInputStream();

byte[] bytes = null;

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] temp = new byte[is.available()];
while (is.read(temp, 0, temp.length) != -1) {
    baos.write(temp);
    temp = new byte[is.available()];
}

bytes = baos.toByteArray();

上記のコードでは、bytesはバイト配列としての応答です。テキストデータの場合は、文字列に変換できます。たとえば、utf-8でエンコードされたテキストとしてのデータです。

String text = new String(bytes, Charset.forName("utf-8"));
0
Amir Amir