HttpURLConnection实现多线程下载资源contentLength()

来源:互联网 发布:证明贪心算法是最优解 编辑:程序博客网 时间:2024/05/17 09:22
package com.example.tyxiong.myapplication;import android.app.Activity;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.EditText;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.ProtocolException;import java.net.URL;import java.util.ArrayList;/** * Android 网络应用. *  3句概述:1 Android支持JDK的TCP/IP UDP的网络通信API.即可用ServiceSocket Socket来建立基于TCP/IP协议的网络通信; *           也可以用DatagramSocket Dategrampacket MuliticastSocket来建立基于UDP协议的网络通信. *         2 Android支持JDK的URL URLConnection等网络通信. *         3 Android内置了HttpClient,方便的发送HTTP请求,简化了与网站间的交互.(可惜没有内置Web Service支持./有ksoap2-android项目) * *         IP协议:实现计算机发送接收分组数据. *         TCP协议:提供可靠无差错的通信服务. 端对端的协议(为两个通信实体之间通信起到了重要作用), 重发机制(接收方收到数据,有应答,若无则发送方重发数据) *         TCP IP功能互补,通常两者结合使用,统称TCP/IP协议. *         TCP/IP协议通信建立过程: 服务器端(主动)接收客户端连接请求(accept()方法),当有客户端(Socket)发送连接请求时, *         方法返回与之对应的Socket;通信链路建立.主客消失,可通过Socket通信. *         使用步骤4步: *          1 服务器端创建ServiceSocket对象,指定端口(大于1024) 默认IP *          2 对象的实例方法accept(),接收客户端请求.阻塞线程,有请求时方法返回Socket对象 *          3 客户端创建Socket对象,连接到指定的服务器端口 new Socket(remoteAddress,port) *          4 两个通信实体可通过Socket通信啦. 有方法getInputStream()/out.. 编码的问题linux平台用UTF-8字符集. * *          注意:android建立网络连接不允许在UI线程中进行. *          设置读取数据超时(BufferReader readLine()阻塞):Socket有方法setSoTimeout(),超时可抛异常 *          设置连接服务器超时:步骤1 建无连接的Socket new Socket() 2 connect()方法设置 * *          网络通信中多线程:服务器端:由于readLine()会阻塞线程,则每个Socket建立一个线程负责. *                          客户端: 同样,需要一个线程读取服务器数据+ 然后主线程负责界面,用户输入. * * *          URL,统一资源定位器,能打开URL指定网络数据的输入流(读取) 2个实例方法openStream()/打开连接的输入流 openURLConnection()/打开应用程序与URL资源间的连接对象 *          URL组成:协议名,主机名,端口,资源. *          读取网络资源2步骤: *              1 创建URL对象   2openStream()打开资源输入流,,读取吧.>>> *     *     URLConnection提交请求:URL对象实例方法openURLConnection()方法->URLConnection对象-->发送请求,获取数据.      *     6方法 2+4 设置请求头字段  setRequestProperty(key,value)设置请求字段的值. addRequestProperty()为指定key追加value值.      *                 获取响应    getContent()/获取该URLConnection内容       *                            getHeaderField(string)获取指定响应头字段的值       *                            getInputStream()/URLConnection输入流,读取响应       *                            getOutputStram()/URLConnection输出流,发送请求参数       *            使用分4步骤:       *                   1 URL对象,方法 获取URLConnection对象       *                   2 设置URLConnection参数及请求字段属性       *                   3 若发送GET请求,直接connect()方法建立实际连接. Post请求则要打开URLConnection的输出流,先发送请求参数.       *                   4 远程资源可用,用获取响应方法读取资源.       *   注意:*****若既要发送请求,又要读取响应内容时,先发,再读.POST请求       *        ****若需发送POST请求,必须设置 setDoOutput(true) setDoInput(true)头字段.       *        ****用完关闭流.try/catch/final       *      *    HttpURLConnection URLConnection子类,增强,为Http访问提供了不4个便捷方法      *                         1 getResponseCode()//获取服务器响应代码      *                         2 getResponseMessage()//响应消息      *                         3 getRequestMethod()//获取发送请求的方法      *                         4 setRequestMethoe()//设置发送请求的方法.      *      *  多线程下载5步:      *         1 URL对象      *         2 获取URL对象指定资源数据大小(getContentLength())      *         3 本地建立与资源相同大小空文件      *         4 平分资源计算每条线程下载的字节部分.      *         5 创建,启动多条线程下载.      *      *      * HttpClient :1概述:Apache组织的项目,Android也内置了HttpClient支持.简单的Http客户端,用于发送HTTP请求      * 接收响应,增强版本的HttpURLConnection.使用5步:  3个对象 3个方法      *     1 创建HttpClient对象      *     2 若发送GET请求--HttpGet对象     POST请求--HttpPost对象      *     3 设置发送请求参数,,,可用setParams()/setEntity()      *     4 HttpClient对象execute()方法发送请求.该方法返回HttpResponse对象      *     5 HttpResponse对象 getEntity()方法,,获取响应内容.      *      *      *     * * * *  HttpURLConnection URLConnection子类,增强,为Http访问提供了不4个便捷方法      *                         1 getResponseCode()//获取服务器响应代码      *                         2 getResponseMessage()//响应消息      *                         3 getRequestMethod()//获取发送请求的方法      *                         4 setRequestMethoe()//设置发送请求的方法.  * */public class MainActivity extends Activity {    EditText show;    Handler handler;    private Thread thread;    EditText fileName;    EditText threadCount;    ProgressDialog progressDialog;    private int progress;    private int MAX = 100;    DownUtils downUtils;    String url;    String path;    int count;    public void send(View view) {//向服务器发送数据....        url = show.getText().toString();        path = fileName.getText().toString();        count = Integer.parseInt(threadCount.getText().toString().trim());        progressDialog.show();        thread.start();    }//发送GET请求...    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        show = (EditText) findViewById(R.id.show);        fileName = (EditText) findViewById(R.id.fileName);        threadCount = (EditText) findViewById(R.id.count);        progressDialog = new ProgressDialog(this);        progressDialog.setTitle("下载");        progressDialog.setIndeterminate(false);        progressDialog.setCancelable(false);        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        progressDialog.setMessage("正在下载...");        progressDialog.setMax(MAX);        handler = new Handler() {            @Override            public void handleMessage(Message msg) {                if (msg.what == 0x11) {                    progressDialog.setProgress(progress);                }            }        };        thread = new Thread() {            @Override            public void run() {                downUtils = new DownUtils(url, path, count);                downUtils.sendGet();                while (progress < MAX) {                    float position = downUtils.getProgress();                    progress = (int) (MAX * position);                    try {                        sleep(1 * 1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    handler.sendEmptyMessage(0x11);                }                progressDialog.dismiss();            }        };    }}class DownUtils {String link;   /*  "http://p.gdown.baidu.com/ab67d1f87dda5edd22d919fc5a33bad644220b671bb3bb17fd6f8849a61ed2c3c7e9c44f13348ef75f6bcbdb8cdc5c867bcf7dd31f353abeb47a285ab0b588c5c0df7dcdbcf395acd80b500258e99d064d92bac54af82bd95b7553bd86e2bc83ce217398cfb18bd8fd5e6a6f506db32f75cb5e965207230404b400a9fdd2fdc8e20c4215f9fde290e5b22eed14479ddd43a35e954f30c2e8ed119b7239a659fbf59390a45f51edaab818ef4eeb14a4011dd043f84f4b70f4d49f8a5b0571d5b1d8bdb84b2d49d3687d5b43e0fe513b59f3beef45c6121fd0088e20ad370cb22e02207716b95d8f627a5fe9d79f99b06852651f73c5d0e63476b8148506a88909fb0947b3e5510573632887aeee2e6b871dfe70d2ee93fc2fad2997f2a2845e1f40ac0b9ddbcf4e679cd8b0600f1a93af5774d530038d59a073d1e7f97ef1b488";*/    String path;    int COUNT;    public DownUtils(String link, String path, int COUNT) {        this.link = link;        this.path = "/mnt/sdcard/"+path;        this.COUNT = COUNT;    }    ArrayList<DownThread> list = new ArrayList<>();    int fileSize = 0;    int subSize = 0;    public float getProgress() {        int num = 0;        for (int i = 0; i < list.size(); i++) {            num += list.get(i).progress;        }        return 1.0f * num / fileSize;    }    public void sendGet() {        RandomAccessFile file = null;        try {            final HttpURLConnection urlConnection;            URL url = new URL(link);            urlConnection = (HttpURLConnection) url.openConnection();//1获取与远程资源的连接.            urlConnection.setConnectTimeout(10 * 1000);            urlConnection.setRequestProperty("accept", "*/*");            urlConnection.setRequestProperty("connection", "Keep-Alive");            urlConnection.setRequestProperty("charset", "utf-8");//设置请求字段属性.            urlConnection.getRequestMethod();            urlConnection.setRequestMethod("GET");                   //便捷方法设置发送请求方法            fileSize = urlConnection.getContentLength();            urlConnection.disconnect();            file = new RandomAccessFile(path, "rw");            file.setLength(fileSize);            Log.w("xxx", "sendGet: 需要下载文件大小" + fileSize);            subSize = fileSize / COUNT;            for (int i = 0; i < COUNT; i++) {                DownThread newThread = new DownThread(i * subSize, subSize);//// TODO: 11/11/2016                list.add(newThread);                newThread.start();            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                assert file != null;                file.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    class DownThread extends Thread {        public int position = 0;        int length = 0;        int progress = 0;        public DownThread(int position, int length) {            this.position = position;            this.length = length;        }        @Override        public void run() {            HttpURLConnection urlConnection;            URL url;            try {                RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw");                url = new URL(link);                urlConnection = (HttpURLConnection) url.openConnection();//1获取与远程资源的连接.                urlConnection.setConnectTimeout(10 * 1000);                urlConnection.setRequestProperty("accept", "*/*");                urlConnection.setRequestProperty("connection", "Keep-Alive");                urlConnection.setRequestProperty("charset", "utf-8");//设置请求字段属性.                urlConnection.getRequestMethod();                urlConnection.setRequestMethod("GET");                   //便捷方法设置发送请求方法                urlConnection.connect();                InputStream inputStream = urlConnection.getInputStream();                long j = 0;                while (j < position) {                    j += inputStream.skip(position - j);                }                randomAccessFile.seek(position);                int read = 0;                byte[] buffer = new byte[1024];                while (progress < length && read != -1) {                    read = inputStream.read(buffer, 0, buffer.length);                    randomAccessFile.write(buffer, 0, read);                    progress += read;                }                randomAccessFile.close();                inputStream.close();            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (ProtocolException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }    }} <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.INTERNET" />![运行效果](http://img.blog.csdn.net/20161112192835504)
0 0
原创粉丝点击