4

我有一些代码可以下载一个 XML 文件,该文件已经在付费应用程序中发布了几年 - 直到我最近看到 HTC One 发生这种情况之前从未遇到任何问题。

想知道我是否遗漏了什么,或者是否应该在某个地方报告。

这是强制问题的示例代码:

package com.lutron.davetest;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.Menu;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView mainCenterText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mainCenterText = (TextView) findViewById(R.id.mainCenterText);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Enter the IP address");
        final EditText edit = new EditText(this);
        builder.setView(edit);
        builder.setPositiveButton("OK", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mainCenterText.setText("");
                String ip = edit.getText().toString();
                new DownloadTask().execute(ip);
            }
        });
        builder.create().show();
    }

    private class DownloadTask extends AsyncTask<String, Void, Void>{

        @Override
        protected Void doInBackground(String... params) {
            try{
                URL url = new URL("http", params[0], 80, "/file.xml");
                URLConnection connection = url.openConnection();
                InputStream in = new BufferedInputStream(connection.getInputStream());
                byte buf[] = new byte[4096];
                int len;
                while((len = in.read(buf)) != -1 ) {
                    final String data = new String(buf, 0, len);
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            mainCenterText.append(data);
                        }
                    });
                }

            }catch(Exception e){
                e.printStackTrace();
            }
            return null;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

发生的情况是,在其他所有设备上,从流中读取时,您只能获取文件内容。

在 HTC One 上,您会得到 THIS,然后是文件内容:

onnection: close

Last-Modified: ???

Content-Type: text/html

这是 Android 4.1.2。

有没有办法配置 URLConnection 来避免这种情况?

4

1 回答 1

1

哇。

深入研究这个问题,我们意识到这只发生在特定页面上,并验证了当这款手机在其浏览器中导航到它们提供的任何页面时,这些 HTTP 标头仍然出现在正文中导致错误。

我今天对一个小型 HTTP 会话进行了 Wireshark,并注意到这些标头被视为正文的一部分!

HTTP 层中的所有换行符都是 \n\r 或 LF CR。

来自 HTTP 1.1 RFC 2616:http ://www.ietf.org/rfc/rfc2616.txt

HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
protocol elements except the entity-body (see appendix 19.3 for
tolerant applications). The end-of-line marker within an entity-body
is defined by its associated media type, as described in section 3.7.

   CRLF           = CR LF

...

    […] a bare CR
or LF MUST NOT be substituted for CRLF within any of the HTTP control
structures (such as header fields and multipart boundaries).

...

6 Response

After receiving and interpreting a request message, a server responds
with an HTTP response message.

   Response      = Status-Line               ; Section 6.1
                   *(( general-header        ; Section 4.5
                    | response-header        ; Section 6.2
                    | entity-header ) CRLF)  ; Section 7.1
                   CRLF
                   [ message-body ]          ; Section 7.2

这似乎是一个大问题 - 然而,应用程序可以持续到现在的唯一方法似乎是应用程序应该容忍单个 LF 的建议 (19.3)。

所以我猜 HTC 在 HTC One 上忽略了这个建议!!:-P

为了解决这个问题,我尝试使用 HttpClient(Android SDK 附带的版本),但这也有同样的问题。我想尝试使用 Apache HTTP Components 中的 jar 文件,但当然这些文件与 Android 框架中的版本存在包名冲突,因此我使用 Jar Jar Links 重新打包了它们。一旦进口被它取代,它就起作用了!

于 2013-06-04T19:15:11.310 回答