一个下载小demo

来源:互联网 发布:长春网络营销软件价格 编辑:程序博客网 时间:2024/04/30 23:47

一个基于HttpURLConnection的下载小demo,支持多线程下载,断点续传下载,重点学习HttpConnection应用,和断点续传,一个很基本,一个很实用

public class MainActivity extends AppCompatActivity{    String path = "http://192.168.51.121:8080/liangzhu.mp3";    int threadCount = 3;    private ProgressBar pb;    private TextView tv;    private Button btn;    int curentProgress = 0;    String sdCardDir = Environment.getExternalStorageDirectory().getPath();    String sdRoot = sdCardDir+"/mrpeng/";    //    String sdRoot = "sdcard/";    int finishedThread = 0;    Handler handler = new Handler()    {        @Override        public void handleMessage(Message msg)        {            tv.setText(pb.getProgress()*100/pb.getMax()+"%");        }    };    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        pb = (ProgressBar)findViewById(R.id.pb);        tv = (TextView)findViewById(R.id.tv);        btn = (Button)findViewById(R.id.btn);        btn.setOnClickListener(new View.OnClickListener()        {            @Override            public void onClick(View v)            {                Thread thread = new Thread()                {                    @Override                    public void run()                    {                        try                        {                            URL url = new URL(path);                            HttpURLConnection conn = (HttpURLConnection)url.openConnection();                            conn.setRequestMethod("GET");                            conn.setConnectTimeout(8000);                            conn.setReadTimeout(8000);                            if(conn.getResponseCode() == 200)                            {                                //文件大小                                int length = conn.getContentLength();                                pb.setMax(length);                                //计算每条线程下载的字节数                                int size = length/threadCount;                                for(int i = 0; i<threadCount; i++)                                {                                    int startIndex = i*size;                                    int endIndex = ( i+1 )*size-1;                                    if(i == threadCount-1)                                    {                                        endIndex = length-1;                                    }                                    Log.e("hhaha", length+"线程"+i+"的下载区间是:"+startIndex+" ~ "+endIndex);                                    new DownLoadThread(i, startIndex, endIndex).start();                                }                            }                        }catch(Exception e)                        {                            e.printStackTrace();                        }                    }                };                thread.start();            }        });    }    private String getFileNameFromUrl(String path)    {        int index = path.lastIndexOf("/");        return path.substring(index+1);    }    private class DownLoadThread extends Thread    {        int threadId;        int startIndex;        int endIndex;        public DownLoadThread(int threadId, int startIndex, int endIndex)        {            this.threadId = threadId;            this.startIndex = startIndex;            this.endIndex = endIndex;        }        /**         * 下载逻辑         */        @Override        public void run()        {            File parent = new File(sdRoot);            if(!parent.exists())            {                parent.mkdir();            }            File fileProgress = new File(sdRoot+threadId+".txt");            int lastProgress = 0;            if(fileProgress.exists())            {                //读取上次下载记录                try                {                    FileInputStream fis = new FileInputStream(fileProgress);                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));                    //上次的下载记录                    lastProgress = Integer.parseInt(bufferedReader.readLine());                    startIndex += lastProgress;//注意,此处为内部类变量,只累加当前线程的下载进度                    curentProgress += lastProgress;//此为全局变量,累加全部的下载进度                    pb.setProgress(curentProgress);                    handler.sendEmptyMessage(0);                    fis.close();                }catch(Exception e)                {                    e.printStackTrace();                }            }            try            {                URL url = new URL(path);                HttpURLConnection conn = (HttpURLConnection)url.openConnection();                conn.setRequestMethod("GET");                conn.setConnectTimeout(8000);                conn.setReadTimeout(8000);                //设置请求的数据区间                conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);                if(conn.getResponseCode() == 206)                {                    InputStream is = conn.getInputStream();                    byte[] bytes = new byte[1024];                    int len = 0;                    //当前线程下载的总长,初始值是上一次下载的进度                    int total = lastProgress;                    File file = new File(sdRoot+getFileNameFromUrl(path));                    RandomAccessFile raf = new RandomAccessFile(file, "rwd");                    raf.seek(startIndex);                    while(( len = is.read(bytes) ) != -1)//从此输入流中将最多 bytes.length 个字节的数据读入一个 byte 数组中。                    {                        raf.write(bytes, 0, len);//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。                        total += len;                        //临时文件                        RandomAccessFile rafProgress = new RandomAccessFile(fileProgress, "rwd");                        rafProgress.write(( total+"" ).getBytes());                        rafProgress.close();                        curentProgress += len;                        pb.setProgress(curentProgress);                        handler.sendEmptyMessage(0);                    }                    raf.close();                    finishedThread++;                    //所有线程下载完毕之后,一起删除记录现在进度的文件                    synchronized(path)                    {                        if(finishedThread == 3)                        {                            for(int i = 0; i<threadCount; i++)                            {                                File f = new File(sdRoot+i+".txt");                                f.delete();                            }                            finishedThread = 0;                        }                    }                }            }catch(Exception e)            {                e.printStackTrace();            }        }    }}

权限

<uses-permission android:name="android.permission.INTERNET"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

源码:源码地址

0 0
原创粉丝点击