多线程下载

本文介绍了一种基于Android平台的多线程下载方法,通过将文件分割为多个部分并使用不同的线程同时下载这些部分来提高下载速度。该方法利用了Async HTTP库,并通过设置HTTP Range头实现了文件的分段下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,先导依赖
compile 'com.loopj.android:android-async-http:1.4.9'
加权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//布局文件
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context="com.bwie.test.thread.MainActivity">
    <TextView
        android:id="@+id/tv_path"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下载地址:"
        android:textSize="25dp"/>
    <Button
        android:onClick="download"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下载"
        android:textSize="25dp"/>
</LinearLayout>
//主要代码
public class MainActivity extends AppCompatActivity {
    protected static final String TAG = "MainActivity";

    //下载线程的数量
    private final static int threadsize = 3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void download(View v){
        new Thread(){
            @Override
            public void run() {
                super.run();
                HttpClient client=new DefaultHttpClient();
                String uri = "http://c.hiphotos.baidu.com/image/pic/item/b90e7bec54e736d1e51217c292504fc2d46269f3.jpg";
                HttpHead request=new HttpHead(uri);
                try {
                    HttpResponse response = client.execute(request);
                    if(response.getStatusLine().getStatusCode()==200){
                        Header[] headers = response.getHeaders("Content-Length");
                        String value = headers[0].getValue();
                        int filelength = Integer.parseInt(value);
                        String name = getFileName(uri);
                        File file = new File(Environment.getExternalStorageDirectory(),name);
                        //随机访问文件
                        RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                        //设置文件的大小
                        raf.setLength(filelength);
                        //关闭
                        raf.close();

                        //计算每条线程的下载量
                        int block = (filelength%threadsize == 0)?(filelength/threadsize):(filelength/threadsize+1);

                        //开启三条线程执行下载
                        for(int threadid=0;threadid<threadsize;threadid++){
                            new DownloadThread(threadid, uri, file, block).start();
                        }

                    }
                } catch (IOException e) {

                }
            }
            private String getFileName(String uri) {
                return uri.substring(uri.lastIndexOf("/")+1);
            }
        }.start();
    }
    //线程下载类
    private class DownloadThread extends Thread{
        private int threadid;//线程的id
        private String uri;//下载的地址
        private File file;//下载文件
        private int block;//下载的块
        private int start;
        private int end;
        public DownloadThread(int threadid, String uri, File file, int block) {
            super();
            this.threadid = threadid;
            this.uri = uri;
            this.file = file;
            this.block = block;
            //计算下载的开始位置和结束位置
            start = threadid * block;
            end = (threadid + 1)*block -1;
        }
        //下载   状态码:200是普通的下载      206是分段下载        Range:范围
        @Override
        public void run() {
            super.run();
            try {
                RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                //跳转到起始位置
                raf.seek(start);

                //分段下载真实内容
                HttpClient client = new DefaultHttpClient();
                HttpGet request = new HttpGet(uri);
                request.addHeader("Range", "bytes:"+start+"-"+end);//添加请求头
                HttpResponse response = client.execute(request);
                if(response.getStatusLine().getStatusCode() == 200){
                    InputStream inputStream = response.getEntity().getContent();
                    //把流写入到文件
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while((len = inputStream.read(buffer)) != -1){

                        //写数据
                        raf.write(buffer, 0, len);
                    }
                    inputStream.close();
                    raf.close();
                    Log.i(TAG, "第"+threadid+"条线程下载完成");
                }

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值