断点继传

import

 java.io.File;


import

 java.net.URL;


import

 java.net.URLConnection;


import

 android.app.Activity;


import

 android.os.Bundle;


import

 android.os.Environment;


import

 android.os.Handler;


import

 android.os.Message;


import

 android.view.View;


import

 android.view.View.OnClickListener;


import

 android.widget.Button;


import

 android.widget.EditText;


import

 android.widget.ProgressBar;


import

 android.widget.TextView;


/**


 *  Copyright (C) 2010 ideasandroid
 *  演示android多线程下载
 *  欢迎访问http://www.ideasandroid.com
 *  让程序开发不再那么神秘
 

*/




public

 

class

 FileDownloadDemo 

extends

 Activity {
 
    

private

 EditText downloadUrl;
    

private

 EditText downloadFileName;
    

private

 EditText downloadThreadNum;
    

private

 Button downloadBt;
    

private

 ProgressBar downloadProgressBar;
    

private

 TextView progressMessage;
    

private

 

int

 downloadedSize 

=

 

0

;
    

private

 

int

 fileSize 

=

 

0

;
 
    @Override
    

public

 

void

 onCreate(Bundle savedInstanceState) {
        

super

.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        downloadUrl 

=

 (EditText) findViewById(R.id.downloadUrl);
        downloadFileName 

=

 (EditText) findViewById(R.id.downloadFileName);
        downloadThreadNum 

=

 (EditText) findViewById(R.id.downloadThreadNum);
        progressMessage 

=

 (TextView) findViewById(R.id.progressMessage);
        downloadBt 

=

 (Button) findViewById(R.id.downloadBt);
        downloadProgressBar 

=

 (ProgressBar) findViewById(R.id.downloadProgressBar);
        downloadProgressBar.setVisibility(View.VISIBLE);
        downloadProgressBar.setMax(

100

);
        downloadProgressBar.setProgress(

0

);
        downloadBt.setOnClickListener(

new

 OnClickListener() {
            

public

 

void

 onClick(View v) {
                download();
            }
        });
    }
 
    

private

 

void

 download() {
        

//

 获取SD卡目录




        String dowloadDir 

=

 Environment.getExternalStorageDirectory()
                

+

 

"

/ideasdownload/

"

;
        File file 

=

 

new

 File(dowloadDir);
        

//

创建下载目录




        

if

 (

!

file.exists()) {
            file.mkdirs();
        }
 
        

//

读取下载线程数,如果为空,则单线程下载




        

int

 downloadTN 

=

 Integer.valueOf(

""

.equals(downloadThreadNum.getText()
                .toString()) 

?

 

"

1

"

 : downloadThreadNum.getText().toString());
        

//

如果下载文件名为空则获取Url尾为文件名




        

int

 fileNameStart 

=

 downloadUrl.getText().toString().lastIndexOf(

"

/

"

);
        String fileName 

=

 

""

.equals(downloadFileName.getText().toString()) 

?

 downloadUrl
                .getText().toString().substring(fileNameStart)
                : downloadFileName.getText().toString();
        

//

开始下载前把下载按钮设置为不可用




        downloadBt.setClickable(

false

);
        

//

进度条设为0




        downloadProgressBar.setProgress(

0

);
        

//

启动文件下载线程




        

new

 downloadTask(downloadUrl.getText().toString(), Integer
                .valueOf(downloadTN), dowloadDir 

+

 fileName).start();
    }
 
    Handler handler 

=

 

new

 Handler() {
        @Override
        

public

 

void

 handleMessage(Message msg) {
            

//

当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息




            

int

 progress 

=

 (Double.valueOf((downloadedSize 

*

 

1.0

 

/

 fileSize 

*

 

100

))).intValue();
            

if

 (progress 

==

 

100

) {
                downloadBt.setClickable(

true

);
                progressMessage.setText(

"

下载完成!

"

);
            } 

else

 {
                progressMessage.setText(

"

当前进度:

"

 

+

 progress 

+

 

"

%

"

);
            }
            downloadProgressBar.setProgress(progress);
        }
 
    };
 
    

/**


     * 

@author

 ideasandroid
     * 主下载线程
     

*/


    

public

 

class

 downloadTask 

extends

 Thread {
        

private

 

int

 blockSize, downloadSizeMore;
        

private

 

int

 threadNum 

=

 

5

;
        String urlStr, threadNo, fileName;
 
        

public

 downloadTask(String urlStr, 

int

 threadNum, String fileName) {
            

this

.urlStr 

=

 urlStr;
            

this

.threadNum 

=

 threadNum;
            

this

.fileName 

=

 fileName;
        }
 
        @Override
        

public

 

void

 run() {
            FileDownloadThread[] fds 

=

 

new

 FileDownloadThread[threadNum];
            

try

 {
                URL url 

=

 

new

 URL(urlStr);
                URLConnection conn 

=

 url.openConnection();
                

//

获取下载文件的总大小




                fileSize 

=

 conn.getContentLength();
                

//

计算每个线程要下载的数据量




                blockSize 

=

 fileSize 

/

 threadNum;
                

//

 解决整除后百分比计算误差




                downloadSizeMore 

=

 (fileSize 

%

 threadNum);
                File file 

=

 

new

 File(fileName);
                

for

 (

int

 i 

=

 

0

; i 

<

 threadNum; i

++

) {
                    

//

启动线程,分别下载自己需要下载的部分




                    FileDownloadThread fdt 

=

 

new

 FileDownloadThread(url, file,
                            i 

*

 blockSize, (i 

+

 

1

) 

*

 blockSize 

-

 

1

);
                    fdt.setName(

"

Thread

"

 

+

 i);
                    fdt.start();
                    fds[i] 

=

 fdt;
                }
                

boolean

 finished 

=

 

false

;
                

while

 (

!

finished) {
                    

//

 先把整除的余数搞定




                    downloadedSize 

=

 downloadSizeMore;
                    finished 

=

 

true

;
                    

for

 (

int

 i 

=

 

0

; i 

<

 fds.length; i

++

) {
                        downloadedSize 

+=

 fds[i].getDownloadSize();
                        

if

 (

!

fds[i].isFinished()) {
                            finished 

=

 

false

;
                        }
                    }
                    

//

通知handler去更新视图组件




                    handler.sendEmptyMessage(

0

);
                    

//

休息1秒后再读取下载进度




                    sleep(

1000

);
                }
            } 

catch

 (Exception e) {
 
            }
 
        }
    }
}


import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.URL; import java.net.URLConnection; import android.util.Log; /** * Copyright (C) 2010 ideasandroid * 演示android多线程下载 * 欢迎访问http://www.ideasandroid.com * 让程序开发不再那么神秘 * * 单个下载线程 */ public class FileDownloadThread extends Thread{ private static final int BUFFER_SIZE = 1024 ; private URL url; private File file; private int startPosition; private int endPosition; private int curPosition; // 用于标识当前线程是否下载完成 private boolean finished = false ; private int downloadSize = 0 ; public FileDownloadThread(URL url,File file, int startPosition, int endPosition){ this .url = url; this .file = file; this .startPosition = startPosition; this .curPosition = startPosition; this .endPosition = endPosition; } @Override public void run() { BufferedInputStream bis = null ; RandomAccessFile fos = null ; byte [] buf = new byte [BUFFER_SIZE]; URLConnection con = null ; try { con = url.openConnection(); con.setAllowUserInteraction( true ); // 设置当前线程下载的起点,终点 con.setRequestProperty( " Range " , " bytes= " + startPosition + " - " + endPosition); // 使用java中的RandomAccessFile 对文件进行随机读写操作 fos = new RandomAccessFile(file, " rw " ); // 设置开始写文件的位置 fos.seek(startPosition); bis = new BufferedInputStream(con.getInputStream()); // 开始循环以流的形式读写文件 while (curPosition < endPosition) { int len = bis.read(buf, 0 , BUFFER_SIZE); if (len == - 1 ) { break ; } fos.write(buf, 0 , len); curPosition = curPosition + len; if (curPosition > endPosition) { downloadSize += len - (curPosition - endPosition) + 1 ; } else { downloadSize += len; } } // 下载完成设为true this .finished = true ; bis.close(); fos.close(); } catch (IOException e) { Log.d(getName() + " Error: " , e.getMessage()); } } public boolean isFinished(){ return finished; } public int getDownloadSize() { return downloadSize; } }

转自http://www.goprogram.org/blog/?p=66
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值