单线程下载
1.单线程下载比较简单,就是开启一个线程,然后打开URL连接按照字节的方式读取流,写入文件就可了
2.用AsyncTask实现单线程下载
class DownLoadSingle extends AsyncTask<String,Integer,String>{
@Override
protected void onProgressUpdate(Integer... values) {
mProgressBar.setProgress((int) (values[0]*100.0/values[1]));//设置下载进度
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
@Override
protected String doInBackground(String... params) {
try {
// URL url=new URL("http://dl.bizhi.sogou.com/images/2015/03/12/1113537.jpg");//网络图片
URL url=new URL("http://192.168.0.103:8080/ThirteenAugMyServer/music/SeeYouAgain.mp3");//本地服务器图片
URLConnection connection=url.openConnection();//打开url
int length=connection.getContentLength();//得到内容长度
InputStream is=connection.getInputStream();//得到输入流
File file=new File(Environment.getExternalStorageDirectory(),"See You Again.mp3");
if (!file.exists()){
file.createNewFile();
}
FileOutputStream os=new FileOutputStream(file);//输出流
byte[] array=new byte[1024];
int sum=0;
int index=is.read(array);
while (index!=-1){
os.write(array,0,index);
sum+=index;
publishProgress(sum,length);
index=is.read(array);
}
os.flush();
os.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
3.然后启动这个线程
DownLoadSingle task=new DownLoadSingle();
task.execute();
多线程下载
1.首先创建一个类继承与Thread,在该类中,构建一个有参构造器,其中包括文件开始位置,文件结束位置,url路径,file路径,然后重写run方法
2.重写run方法中,首先打开url路径,设置文件下载起始和结束位置,然后对文件进行读写操作
public class MultiThread extends Thread {
private long start;
private long end;
private String urlPath;
private String filePath;
private int sum=0;
public int getSum() {
return sum;
}
/***
* 多线程构造器,用于传入下载内容的起始,末尾,url路径,file路径
* @param start 下载内容的起始位置
* @param end 下载内容的末位置
* @param urlPath url路径
* @param filePath file路径
*/
public MultiThread(long start, long end, String urlPath, String filePath) {
this.start = start;
this.end = end;
this.urlPath = urlPath;
this.filePath = filePath;
}
//重写了run方法
@Override
public void run() {
try {
URL url=new URL(urlPath);
URLConnection connection=url.openConnection();//打开url路径
connection.setAllowUserInteraction(true);//
connection.setRequestProperty("Range", "bytes=" + start + "-"
+ end);//返回此连接指定的一般请求属性值
InputStream is=connection.getInputStream();
byte[] array=new byte[1024];
int index=is.read(array);
File file=new File(filePath);
RandomAccessFile randomAccessFile=new RandomAccessFile(file,"rw");//随机文件的读取和写入,“rw”表示写入文件
randomAccessFile.seek(start);//设置到文件开头测量到的文件指针偏移量
while (index!=-1){
randomAccessFile.write(array,0,index);
sum+=index; //将在在的总字节数返回到sum中
index=is.read(array);
}
//关闭流
randomAccessFile.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.创建一个新的线程,打开url路径,得到文件的总大小,然后创建一个文件,将url所指的文件写入到该文件中,然后创建5个线程,对这五个线程分别分配不同的起始位置,在将创建的线程放入到线程数组中去,方便管理,同时得到下载进度的信息
new Thread(new Runnable() {
@Override
public void run() {
// String urlPath="http://dl.bizhi.sogou.com/images/2015/03/12/1113537.jpg";
String urlPath="http://192.168.0.100:8080/ThirteenAugMyServer/music/SeeYouAgain.mp3";
URL url= null;
try {
url = new URL(urlPath);
URLConnection connection=url.openConnection();
length=connection.getContentLength();
File file=new File(Environment.getExternalStorageDirectory(),"SeeYouAgain.mp3");
if (!file.exists()){
file.createNewFile();
}
//开启5个线程,将5个线程放入到线程数组中,然后用于得到文件下载进度信息
MultiThread[] threads=new MultiThread[5];
for (int i=0;i<5;i++){
MultiThread thread=null;
if(i==4){
thread = new MultiThread(length / 5*4, length , urlPath, file.getAbsolutePath());
}else {
thread = new MultiThread(length / 5 * i, length / 5 * (i + 1)-1, urlPath, file.getAbsolutePath());
}
thread.start();
threads[i]=thread;
}
//得到下载资源的数量,用来设置进度条
boolean isFinish=true;
while (isFinish){
int sum=0;
for(MultiThread thread:threads){
sum+=thread.getSum();
}
handler.obtainMessage();
Message msg=new Message();
msg.what=DOWN_SUM;
msg.arg1=sum;
handler.sendMessage(msg);
if (sum+10>=length){
isFinish=false;
}
//为何要加休眠,不加休眠会报错
//是为了给progressBar反应的时间
Thread.sleep(1000);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
4.设置进度条
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case DOWN_SUM:
mProgressBar.setProgress((int) (msg.arg1*100.0/length));
break;
default:
break;
}
}
};