Android实现多线程断点下载的方法
本文实例讲述了Android实现多线程断点下载的方法。分享给大家供大家参考。具体实现方法如下:
packagecn.itcast.download; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileNotFoundException; importjava.io.FileOutputStream; importjava.io.IOException; importjava.io.InputStream; importjava.io.RandomAccessFile; importjava.net.HttpURLConnection; importjava.net.MalformedURLException; importjava.net.ProtocolException; importjava.net.URL; importcn.itcast.mutiledownload.StreamTool; importandroid.app.Activity; importandroid.os.Bundle; importandroid.os.Handler; importandroid.os.Message; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.EditText; importandroid.widget.ProgressBar; importandroid.widget.TextView; importandroid.widget.Toast; publicclassMutiledownloadActivityextendsActivityimplementsOnClickListener{ privateProgressBarpb; privateButtonbt; privateTextViewtv; privateEditTextet; booleanflag=true; booleanstopflag=false; privateHandlerhandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ pb.setProgress(total); intmax=pb.getMax(); if(total>=(max-1)){ total=max; flag=false; } intresult=total*100/max; tv.setText("当前进度:"+result+"%"); super.handleMessage(msg); } }; inttotal=0; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); pb=(ProgressBar)this.findViewById(R.id.pb); bt=(Button)this.findViewById(R.id.bt); tv=(TextView)this.findViewById(R.id.tv_process); et=(EditText)this.findViewById(R.id.et); bt.setOnClickListener(this); } @Override publicvoidonClick(Viewv){ switch(v.getId()){ caseR.id.bt: //创建一个子线程定期的更新ui if("开始下载".equals(bt.getText().toString())){ bt.setText("暂停"); stopflag=false;//开始下载 } else{ bt.setText("开始下载"); stopflag=true; } newThread(){ @Override publicvoidrun(){ super.run(); while(flag){ try{ sleep(1000); //如果total>=文件长度 Messagemsg=newMessage(); handler.sendMessage(msg); }catch(InterruptedExceptione){ e.printStackTrace(); } } } }.start(); //开始执行下载的操作 Stringpath=et.getText().toString().trim(); if("".equals(path)){ Toast.makeText(this,"路径不能为空",1).show(); return; } try{ URLurl=newURL(path); HttpURLConnectionconn=(HttpURLConnection)url .openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("User-Agent", "Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)"); intcode=conn.getResponseCode(); if(code==200){ intlen=conn.getContentLength(); RandomAccessFilefile=newRandomAccessFile( "/mnt/sdcard/"+getFilenName(path),"rwd"); //1.设置本地文件大小跟服务器的文件大小一致 file.setLength(len); //设置进度条的最大值 pb.setMax(len); //2.假设开启3个线程 intthreadnumber=3; intblocksize=len/threadnumber; /** *线程10~blocksize线程21*bolocksize~2*blocksize线程3 *2*blocksize~文件末尾 */ for(inti=0;i<threadnumber;i++){ intstartposition=i*blocksize; intendpositon=(i+1)*blocksize; if(i==(threadnumber-1)){ //最后一个线程 endpositon=len; } DownLoadTasktask=newDownLoadTask(i,path, startposition,endpositon); task.start(); } } }catch(Exceptione){ Toast.makeText(this,"下载出现异常",0).show(); e.printStackTrace(); } break; } } classDownLoadTaskextendsThread{ intthreadid; Stringfilepath; intstartposition; intendpositon; publicDownLoadTask(intthreadid,Stringfilepath,intstartposition, intendpositon){ this.threadid=threadid; this.filepath=filepath; this.startposition=startposition; this.endpositon=endpositon; } @Override publicvoidrun(){ try{ Filepostionfile=newFile("/mnt/sdcard/"+threadid+".txt"); URLurl=newURL(filepath); HttpURLConnectionconn=(HttpURLConnection)url .openConnection(); System.out.println("线程"+threadid+"正在下载"+"开始位置:" +startposition+"结束位置"+endpositon); if(postionfile.exists()){ FileInputStreamfis=newFileInputStream(postionfile); byte[]result=StreamTool.getBytes(fis); Stringstr=newString(result); if(!"".equals(str)){ intnewstartposition=Integer.parseInt(str); if(newstartposition>startposition){ startposition=newstartposition; } } } //"Range","bytes=2097152-4194303") conn.setRequestProperty("Range","bytes="+startposition+"-" +endpositon); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("User-Agent", "Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)"); InputStreamis=conn.getInputStream(); RandomAccessFilefile=newRandomAccessFile("/mnt/sdcard/" +getFilenName(filepath),"rwd"); //设置数据从文件哪个位置开始写 file.seek(startposition); byte[]buffer=newbyte[1024]; intlen=0; //代表当前读到的服务器数据的位置,同时这个值已经存储的文件的位置 intcurrentPostion=startposition; //创建一个文件对象,记录当前某个文件的下载位置 while((len=is.read(buffer))!=-1){ if(stopflag){ return; } file.write(buffer,0,len); synchronized(MutiledownloadActivity.this){ total+=len; } currentPostion+=len; //需要把currentPostion信息给持久化到存储设备 Stringposition=currentPostion+""; FileOutputStreamfos=newFileOutputStream(postionfile); fos.write(position.getBytes()); fos.flush(); fos.close(); } file.close(); System.out.println("线程"+threadid+"下载完毕"); //当线程下载完毕后把文件删除掉 if(postionfile.exists()){ postionfile.delete(); } }catch(Exceptione){ e.printStackTrace(); } super.run(); } } publicStringgetFilenName(Stringpath){ intstart=path.lastIndexOf("/")+1; returnpath.substring(start,path.length()); } }
希望本文所述对大家的Android程序设计有所帮助。