HttpUrlConnection的使用

Android的网络请求最纯粹的莫过于HttpUrlConnection了,大部分的网络请求框架也是基于此的,下面讲讲其基本用法

HttpURLConnection connection = null;
        InputStream inputStream = null;
        byte[] buffer = null;
        ByteArrayPool pool = null;
        PoolingByteArrayOutputStream bytes = null;
        try {
            //1.根据请求地址生成url
            URL url = new URL("你的请求地址");
            //2.生成HttpUrlConnection对象
            connection = (HttpURLConnection) url.openConnection();
            //3.设置connection的配置
            connection.setInstanceFollowRedirects(HttpURLConnection.getFollowRedirects());//是否允许重定向,默认true
            connection.setConnectTimeout(10000);//设置连接的超时时间
            connection.setReadTimeout(10000);//设置读取数据的超时时间
            connection.setUseCaches(false);//设置是否使用缓存
            connection.setDoInput(true);//设置是否允许输入
            if ("https".equals(url.getProtocol())) {
                ((HttpsURLConnection) connection).setSSLSocketFactory(null);// 对 HTTPS 使用调用者提供的自定义 SslSocketFactory(如果有),一般不用
            }
            connection.setRequestProperty("", "");//设置请求头
            connection.setRequestMethod("GET");//设置请求方式,"GET" "POST"
            /****************POST请求添加 开始************************/
            Map<String, String> params = null;//假设这个是你的请求参数,我们先转成合适的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (entry.getKey() != null && entry.getValue() == null) {
                    sb.append(URLEncoder.encode(entry.getKey(), "UTF-8"));//编码根据实际业务改动,一般为UTF-8
                    sb.append('=');
                    sb.append(URLEncoder.encode(entry.getValue(), "UTF-8"));//编码根据实际业务改动,一般为UTF-8
                    sb.append('&');
                }
            }
            byte[] postByt = sb.toString().getBytes("UTF-8");//得到向后台发送的数据
            connection.setDoOutput(true);//设置向后台可输出数据
            if (!connection.getRequestProperties().containsKey("Content-Type")) {
                connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置内容类型
            }
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.write(postByt);//向后台发送数据
            out.close();
            /****************POST请求添加 结束************************/
            //4.获取响应结果
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK){//请求成功
                int contentLength = connection.getContentLength();//获取数据长度
                inputStream = connection.getInputStream();//获取输入数据流

                /****************将输入数据流转成字符串 开始************************/
                pool = new ByteArrayPool(4096);
                bytes = new PoolingByteArrayOutputStream(pool, contentLength);
                buffer = pool.getBuf(1024);
                int count;
                while ((count = inputStream.read(buffer)) != -1) {
                    bytes.write(buffer, 0, count);
                }
                byte[] respByt = bytes.toByteArray();
                String resultData = new String(respByt, "UTF-8");//此处的编码UTF-8可以根据业务需求变化,也可以从响应头里面获取
                /****************将输入数据流转成字符串 结束************************/

            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //5.进行关流操作
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                pool.returnBuf(buffer);
                try {
                    bytes.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null){
                connection.disconnect();
            }
        }

PoolingByteArrayOutputStream.java

public class PoolingByteArrayOutputStream extends ByteArrayOutputStream {
    /**
     * If the {@link #PoolingByteArrayOutputStream(ByteArrayPool)} constructor is called, this is
     * the default size to which the underlying byte array is initialized.
     */
    private static final int DEFAULT_SIZE = 256;

    private final ByteArrayPool mPool;

    /**
     * Constructs a new PoolingByteArrayOutputStream with a default size. If more bytes are written
     * to this instance, the underlying byte array will expand.
     */
    public PoolingByteArrayOutputStream(ByteArrayPool pool) {
        this(pool, DEFAULT_SIZE);
    }

    /**
     * Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If
     * more than {@code size} bytes are written to this instance, the underlying byte array will
     * expand.
     *
     * @param size initial size for the underlying byte array. The value will be pinned to a default
     *     minimum size.
     */
    public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) {
        mPool = pool;
        buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE));
    }

    @Override
    public void close() throws IOException {
        mPool.returnBuf(buf);
        buf = null;
        super.close();
    }

    @Override
    public void finalize() {
        mPool.returnBuf(buf);
    }

    /** Ensures there is enough space in the buffer for the given number of additional bytes. */
    @SuppressWarnings("UnsafeFinalization")
    private void expand(int i) {
        /* Can the buffer handle @i more bytes, if not expand it */
        if (count + i <= buf.length) {
            return;
        }
        byte[] newbuf = mPool.getBuf((count + i) * 2);
        System.arraycopy(buf, 0, newbuf, 0, count);
        mPool.returnBuf(buf);
        buf = newbuf;
    }

    @Override
    public synchronized void write(byte[] buffer, int offset, int len) {
        expand(len);
        super.write(buffer, offset, len);
    }

    @Override
    public synchronized void write(int oneByte) {
        expand(1);
        super.write(oneByte);
    }
}

ByteArrayPool.java

public class ByteArrayPool {
    /** The buffer pool, arranged both by last use and by buffer size */
    private final List<byte[]> mBuffersByLastUse = new ArrayList<>();

    private final List<byte[]> mBuffersBySize = new ArrayList<>(64);

    /** The total size of the buffers in the pool */
    private int mCurrentSize = 0;

    /**
     * The maximum aggregate size of the buffers in the pool. Old buffers are discarded to stay
     * under this limit.
     */
    private final int mSizeLimit;

    /** Compares buffers by size */
    protected static final Comparator<byte[]> BUF_COMPARATOR =
            new Comparator<byte[]>() {
                @Override
                public int compare(byte[] lhs, byte[] rhs) {
                    return lhs.length - rhs.length;
                }
            };

    /** @param sizeLimit the maximum size of the pool, in bytes */
    public ByteArrayPool(int sizeLimit) {
        mSizeLimit = sizeLimit;
    }

    /**
     * Returns a buffer from the pool if one is available in the requested size, or allocates a new
     * one if a pooled one is not available.
     *
     * @param len the minimum size, in bytes, of the requested buffer. The returned buffer may be
     *     larger.
     * @return a byte[] buffer is always returned.
     */
    public synchronized byte[] getBuf(int len) {
        for (int i = 0; i < mBuffersBySize.size(); i++) {
            byte[] buf = mBuffersBySize.get(i);
            if (buf.length >= len) {
                mCurrentSize -= buf.length;
                mBuffersBySize.remove(i);
                mBuffersByLastUse.remove(buf);
                return buf;
            }
        }
        return new byte[len];
    }

    /**
     * Returns a buffer to the pool, throwing away old buffers if the pool would exceed its allotted
     * size.
     *
     * @param buf the buffer to return to the pool.
     */
    public synchronized void returnBuf(byte[] buf) {
        if (buf == null || buf.length > mSizeLimit) {
            return;
        }
        mBuffersByLastUse.add(buf);
        int pos = Collections.binarySearch(mBuffersBySize, buf, BUF_COMPARATOR);
        if (pos < 0) {
            pos = -pos - 1;
        }
        mBuffersBySize.add(pos, buf);
        mCurrentSize += buf.length;
        trim();
    }

    /** Removes buffers from the pool until it is under its size limit. */
    private synchronized void trim() {
        while (mCurrentSize > mSizeLimit) {
            byte[] buf = mBuffersByLastUse.remove(0);
            mBuffersBySize.remove(buf);
            mCurrentSize -= buf.length;
        }
    }
}
posted @ 2022-08-10 14:57  呢哇哦比较  阅读(236)  评论(0)    收藏  举报