Multi-thread breakpoint download for Android

Source: Internet
Author: User

This case is to implement multi‑thread breakpoint download of an object, that is, after a part of the object is interrupted, you can continue to download the object with the current progress and display the progress through the progress bar. That is to say, when the file starts to be downloaded, the local file with the download progress of each thread is automatically created. After the download is interrupted, click Download again to check whether the local file exists. If yes, obtain the download progress of the local file and continue the download. After the download is complete, the local file is automatically deleted.

1. Define the attribute names and content required for the layout File


2. Set your Internet permissions and SD card Permissions

 
 
 

3. Start interface Layout

The basic information is as follows:


Two TextView controls, one EditText control, one Button control, and one ProgressBar control are used. <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + 0OjSqtei0uK1xMrHo7q9 + LbIzPXTwzxQcm9ncmVzc0JhciAvPr/YvP6jrMno1sNzeXRsZcr00NSjunN0eWxlPQ = "? Android: attr/progressBarStyleHorizontal"

4. The main program of MainActivity is as follows, and the code has a detailed explanation:

Package www.csdn.net. download; import java. io. file; import java. io. fileInputStream; import java. io. fileNotFoundException; import java. io. inputStream; import java. io. randomAccessFile; import java.net. httpURLConnection; import java.net. URL; import www.csdn.net. utils. streamTools; import android. r. integer; import android. app. activity; import android. OS. bundle; import android. OS. environment; import android. text. text Utils; import android. view. view; import android. widget. editText; import android. widget. progressBar; import android. widget. textView; import android. widget. toast; public class DownloadActivity extends Activity {// Number of threads enabled private int threadNum = 3; private int threadRunning = 3; private EditText et_url; private ProgressBar progressBar; private TextView TV _pb; private int currentProgress; @ Overrideprotected void OnCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_download); // obtain the control object et_url = (EditText) findViewById (R. id. et_url); progressBar = (ProgressBar) findViewById (R. id. pb_down); TV _pb = (TextView) findViewById (R. id. TV _pb); File sdDir = Environment. getExternalStorageDirectory (); File pbFile = new File (sdDir, "pb.txt"); InputStream is = null; try {// determine whether the File exists If (pbFile. exists () {is = new FileInputStream (pbFile) ;}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke. printStackTrace ();} if (is! = Null) {String value = StreamTools. streamToStr (is); String [] arr = value. split (";"); progressBar. setMax (Integer. valueOf (arr [0]); // maximum value currentProgress = Integer. valueOf (arr [1]); // current value progressBar. setProgress (currentProgress); TV _pb.setText ("the current progress is:" + arr [2]); // display percentage }/// download the file (get the server-side file size) public void downLoadFile (View v) {// obtain the download path final String spec = et_url.getText (). toString (); if (TextUtils. isEmpty (spec )) {Toast. makeText (this, "the download address cannot be blank", Toast. LENGTH_LONG ). show () ;}else {new Thread () {public void run () {// HttpURLConnectiontry {// construct the URL object URL = new url (spec) based on the download address ); // open the connection through the openConnection () method of the URL object and return a connection object HttpURLConnection httpURLConnection = (HttpURLConnection) url. openConnection (); // sets the request header httpURLConnection. setRequestMethod ("GET"); httpURLConnection. setReadTimeout (5000); httpURLConnection. se TConnectTimeout (5000); // determines whether the response is successful if (httpURLConnection. getResponseCode () = 200) {// get the length of the downloaded object int fileLength = httpURLConnection. getContentLength (); // set the maximum value of the progress bar. setMax (fileLength); // determines whether the SD card works. if (Environment. getExternalStorageState (). equals (Environment. MEDIA_MOUNTED) {// save the File // path of the External Storage Device File sdFile = Environment. getExternalStorageDirectory (); // get the file name String fileName = spec. substring (spec. LastIndexOf ("/") + 1); // create a File file = new File (sdFile, fileName ); // create the Random Access Object RandomAccessFile accessFile = new RandomAccessFile (file, "rwd"); // save the file size accessFile. setLength (fileLength); // close accessFile. close (); // calculate the download size of each thread. int threadSize = fileLength/threadNum; // calculate the start position and end position of each thread. for (int threadId = 1; threadId <= 3; threadId ++) {int startIndex = (threadId-1) * threadSize; int endIndex = th ReadId * threadSize-1; if (threadId = threadNum) {// The last thread endIndex = fileLength-1;} System. out. println ("current thread:" + threadId + "start position:" + startIndex + "end position:" + endIndex + "thread size:" + threadSize ); // enable the thread to download new DownLoadThread (threadId, startIndex, endIndex, spec ). start () ;}} else {DownloadActivity. this. runOnUiThread (new Runnable () {public void run () {Toast. makeText (DownloadActivity. this, "SD card is not used", Toast. LENGTH_LONG ). show () ;}}) ;}} else {// run DownloadActivity in the main thread. this. runOnUiThread (new Runnable () {public void run () {Toast. makeText (DownloadActivity. this, "server return error", Toast. LENGTH_LONG ). show () ;}) ;}} catch (Exception e) {// TODO Auto-generated catch blocke. printStackTrace ();}};}. start () ;}} class DownLoadThread extends Thread {private int threadId; private int startIndex; private int endIndex; private Stri Ng path; /*** constructor ** @ param threadId * thread serial number * @ param startIndex * thread start position * @ param endIndex * @ param path */public DownLoadThread (int threadId, int startIndex, int endIndex, String path) {super (); this. threadId = threadId; this. startIndex = startIndex; this. endIndex = endIndex; this. path = path ;}@ Overridepublic void run () {try {File sdFile = Environment. getExternalStorageDirectory (); // gets the recording file Fi downloaded by each thread Le recordFile = new File (sdFile, threadId + ". txt "); if (recordFile. exists () {// read the file content InputStream is = new FileInputStream (recordFile); // use the tool class to convert String value = StreamTools. streamToStr (is); // the position where the record is obtained. int recordIndex = Integer. parseInt (value); // assign the record location to the start position startIndex = recordIndex;} // construct the URL object URL = new url (path) through the path ); // open the connection through the openConnection () method of the URL object and return a connection object HttpURLConnection httpURLConnecti On = (HttpURLConnection) url. openConnection (); // sets the request header httpURLConnection. setRequestMethod ("GET"); httpURLConnection. setReadTimeout (5000); // sets the start position and end position of the downloaded file. httpURLConnection. setRequestProperty ("Range", "bytes =" + startIndex + "-" + endIndex); // The obtained status code int code = httpURLConnection. getResponseCode (); // determine whether the request is successful if (code = 206) {// obtain the stream object InputStream returned by each thread is = httpURLConnection. getInputStream (); // get the object name St Ring fileName = path. substring (path. lastIndexOf ("/") + 1); // create a File file File = new File (sdFile, fileName) based on the path ); // create the RandomAccessFile object RandomAccessFile raf = new RandomAccessFile (file, "rwd"); raf. seek (startIndex); // defines the read length int len = 0; // defines the buffer byte B [] = new byte [1024*1024]; int total = 0; // read the while (len = is. read (B ))! =-1) {RandomAccessFile threadFile = new RandomAccessFile (new File (sdFile, threadId + ". txt ")," rwd "); threadFile. writeBytes (startIndex + total) + ""); threadFile. close (); raf. write (B, 0, len); // The downloaded size total + = len; // solve the synchronization problem synchronized (DownloadActivity. this) {currentProgress + = len; progressBar. setProgress (currentProgress); // The percentage calculation operation l indicates long final String percent = currentProgress * 100l/progressBar. getMax () + "%"; DownloadActivity. this. runOnUiThread (new Runnable () {public void run () {TV _pb.setText ("the current progress is:" + percent );}}); // create an operation to save the current progress and percentage. RandomAccessFile pbFile = new RandomAccessFile (new File (sdFile, "pb.txt"), "rwd"); pbFile. writeBytes (progressBar. getMax () + ";" + currentProgress + ";" + percent); pbFile. close () ;}} raf. close (); is. close (); runOnUiThread (new Runnable () {public void run () {Toast. makeText (DownloadActivity. this, "current thread --" + threadId + "-- download completed", Toast. LENGTH_LONG ). show () ;}}); deleteRecordFiles () ;}else {runOnUiThread (new Runnable () {public void run () {Toast. makeText (DownloadActivity. this, "Server Download error", Toast. LENGTH_LONG ). show () ;}) ;}} catch (Exception e) {// TODO Auto-generated catch blocke. printStackTrace () ;}}// synchronized prevents threads from synchronizing public synchronized void deleteRecordFiles () {File sdFile = Environment. getExternalStorageDirectory (); threadRunning --; if (threadRunning = 0) {for (int I = 1; I <= 3; I ++) {File recordFile = new File (sdFile, I + ". txt "); if (recordFile. exists () {// delete the file recordFile. delete ();} File pbFile = new File (sdFile, "pb.txt"); if (pbFile. exists () {pbFile. delete ();}}}}}

A StreamTools method can be encapsulated for stream output and applied in the main program. The Code is as follows:

Package www.csdn.net. utils; import java. io. byteArrayOutputStream; import java. io. IOException; import java. io. inputStream; public class StreamTools {public static String streamToStr (InputStream is) {String value = null; try {ByteArrayOutputStream baos = new ByteArrayOutputStream (); // define the read length int len = 0; // define the buffer byte B [] = new byte [1024]; // read while cyclically (len = is. read (B ))! =-1) {baos. write (B, 0, len);} baos. close (); is. close (); value = new String (baos. toByteArray ();} catch (IOException e) {// TODO Auto-generated catch blocke. printStackTrace ();} return value ;}}
5. program running result


The temporary files in the SD card are automatically deleted after the download is completed:


6. possible causes of bugs include:

The Internet permission is not added, the server is not started, the download path is incorrect, and the control object is not obtained.

If the progress displayed on the progress bar is negative during file download, it may be because the percentage of the file exceeds the memory space. Solution: add l after 100 when defining the percentage, string percent = currentProgress * 100l/progressBar. getMax () + "% ".



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.