android多线程下载

来源:互联网 发布:mac如何截屏快捷键 编辑:程序博客网 时间:2024/06/16 05:54

使用单线程下载文件会比较慢,如果使用n个线程,那么时间就会缩短为1/n,每个线程只下载其中的一段,都下载完以后再把这n段拼接起来就ok了。下面简单介绍一下多线程下载的原理和实现。


多线程下载的关键是怎样从服务器只获取文件的一部分,而不是整个文件。这里需要设置request header的一个属性:Range。

conn.setRequestProperty("Range", "bytes=" + start + "-" + end);

还有下载完毕后怎么把多个文件片段合并到一起的问题。可以使用RandomAccessFile,但要注意:每个线程需要建自己的RandomAccessFile对象,它们可以共同操作一个File,但不能使用同一个RandomAccessFile。


完整代码:

public class MainActivity extends ActionBarActivity {    public static final String TEST_URL = "http://gdown.baidu.com/data/wisegame/e59f42264a98b05e/WeChat_861.apk";    private TextView[] tv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        TextView tv1 = (TextView) findViewById(R.id.tv1);        TextView tv2 = (TextView) findViewById(R.id.tv2);        TextView tv3 = (TextView) findViewById(R.id.tv3);        tv = new TextView[3];        tv[0] = tv1;  tv[1] = tv2;  tv[2] = tv3;        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread() {                    @Override                    public void run() {                        try {                            URL url = new URL(TEST_URL);                            HttpURLConnection conn = (HttpURLConnection) url.openConnection();                            conn.setRequestMethod("GET");                            conn.setConnectTimeout(5000);                            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");                            String fileName = TEST_URL.substring(TEST_URL.lastIndexOf("/") + 1);                            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), fileName);                            int totalLength = conn.getContentLength();                            int subLength = totalLength / 3;                            for(int i = 0; i < 3; i++){                                int start = i * subLength;                                int end = (i+1) * subLength - 1;                                if(i == 2){                                    end = totalLength;                                }                                new DownloadThread(i, start, end, file, url).start();                            }                        } catch (MalformedURLException e) {                            e.printStackTrace();                        } catch (IOException e) {                            e.printStackTrace();                        }                    }                }.start();            }        });    }    class DownloadThread extends Thread{        int threadId;        int start;        int end;        File file;        URL url;        int currLength = 0;        int totalLength;        public DownloadThread(int threadId, int start, int end, File file, URL url){            this.threadId = threadId;            this.start = start;            this.end = end;            this.file = file;            this.url = url;            totalLength = end - start + 1;        }        @Override        public void run() {            try {                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                conn.setRequestMethod("GET");                conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");                conn.setRequestProperty("Range", "bytes=" + start + "-" + end);                RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");                randomAccessFile.seek(start);                InputStream is = conn.getInputStream();                byte[] buf = new byte[4 * 1024];                int len;                while((len = is.read(buf)) != -1){                    currLength += len;                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            tv[threadId].setText("进程" + (threadId + 1) + " 下载进度:" + currLength + "/" + totalLength);                        }                    });                    randomAccessFile.write(buf, 0, len);                }                is.close();                randomAccessFile.close();            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }    }}
0 0
原创粉丝点击