关于httpurlconnection getcontentlength返回值为-1的问题

在做AsyncTask异步任务读取网络数据的时候,发现了httpUrlConnection的获取数据内容长度(connection.getContentLength())总是为-1。导致进度条一直为灰色状态。预期结果应如图所示:

关于httpurlconnection getcontentlength返回值为-1的问题_第1张图片

而现在的效果是这样的:

关于httpurlconnection getcontentlength返回值为-1的问题_第2张图片

MainActivity代码如下:

import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


public class MainActivity extends ActionBarActivity {

    private Button executeBtn;
    private Button cancelBtn;
    private MyTask myTask;
    private TextView resultTxt;
    public ProgressBar progressBar;

    private View.OnClickListener executeBtnListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           myTask = new MyTask();
            myTask.execute("https://www.baidu.com");
            executeBtn.setEnabled(false);
            cancelBtn.setEnabled(true);
        }
    };
    private View.OnClickListener cancelBtnListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myTask.cancel(true);

        }
    };


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

        executeBtn = (Button) findViewById(R.id.executeBtn);
        cancelBtn = (Button) findViewById(R.id.cancelBtn);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        resultTxt = (TextView) findViewById(R.id.resultTxt);

        executeBtn.setOnClickListener(executeBtnListener);
        cancelBtn.setOnClickListener(cancelBtnListener);
    }

    public class MyTask extends AsyncTask {

        private static final String TAG = "ASYNC_TASK";

        /**
         * Override this method to perform a computation on a background thread. The
         * specified parameters are the parameters passed to {@link #execute}
         * by the caller of this task.
         * 

* This method can call {@link #publishProgress} to publish updates * on the UI thread. * * @param params The parameters of the task. * @return A result, defined by the subclass of this task. * @see #onPreExecute() * @see #onPostExecute * @see #publishProgress */ @Override protected String doInBackground(String... params) { try { URL url = new URL(params[0]); URLConnection connection = url.openConnection(); // connection.setRequestProperty("Accept-Encoding", "identity"); long total = connection.getContentLength(); InputStream inputStream = connection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[256]; int count = 0; int length = -1; while((length = inputStream.read(buf)) != -1){ baos.write(buf,0,length); count += length; publishProgress((int)((count/(float)total)*100)); Thread.sleep(500); } inputStream.close(); return new String(baos.toByteArray(),"utf-8"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); resultTxt.setText(s); executeBtn.setEnabled(true); cancelBtn.setEnabled(false); } @Override protected void onProgressUpdate(Integer... values) { Log.i(TAG, "onProgressUpdate(Progress... progresses) called"); progressBar.setProgress(values[0]); // System.out.print(values[0]); } @Override protected void onCancelled(String s) { super.onCancelled(s); } @Override protected void onCancelled() { super.onCancelled(); resultTxt.setText("cancelled!"); progressBar.setProgress(0); executeBtn.setEnabled(true); cancelBtn.setEnabled(false); } } }

使用System.out.println()输出total为-1,肯定是connection.getContentLength()有问题,现在来看一下这个方法的api: By default, this implementation of HttpURLConnection requests that servers use gzip compression. Since getContentLength() returns the number of bytes transmitted, you cannot use that method to predict how many bytes can be read from getInputStream(). Instead, read that stream until it is exhausted: whenread() returns -1.原来获取的数据是采用gzip压缩的格式的,所以读不出来数据。找到了问题就该找解决办法了,在connection.getContentLength()前面加上使用
connection.setRequestProperty("Accept-Encoding", "identity");
setRequestProperty主要是设置HttpURLConnection请求头里面的属性,比如请求内容格式、Cookie、User-Agent(浏览器类型)等等。

最后实现效果如图所示:

关于httpurlconnection getcontentlength返回值为-1的问题_第3张图片

最终结果:

关于httpurlconnection getcontentlength返回值为-1的问题_第4张图片

你可能感兴趣的:(安卓)