A blogger in front of

, "AsyncTask to implement a breakpoint " explains how to implement a broken point on a single thread, that is, a file has only one thread to download.

: for large files, multithreaded downloads will be faster than single threaded downloads. Multi thread download is a little more complicated than single thread download. This blog will explain in detail how to use AsyncTask to achieve multithread breakpoint and continue download.

1, implement the principle

multithread downloading first through the total number of downloaded threads per file (I set 5 here) to determine the starting and stop locations for each thread to be downloaded.

 long blockLength = mFileLength / DEFAULT_POOL_SIZE; for (int i = 0; I < DEFAULT_POOL_SIZE;) {/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = DEFAULT_POOL_SIZE; int i = 0; I < DEFAULT_POOL_SIZE; SIZE - 1)) {endPosition = mFileLength; / / / / / if the size of the whole file is not an integer multiple of the number of threads, the end of the last thread is the total length of the file}...}

here needs to be noted that the size of the file is often not an integer multiple of the number of threads, so the last one The ending position of the thread needs to be set to file length. When

determines that each thread is downloaded, the HTTP request header needs to be set to download the specified location of the file:

 / / / / / / / / / / / / / / / / / / / / endPosition byte Header header_size = new BasicHeader (Range, "Range," + "+" + "+ +) Tion); request.addHeader (header_size); 

above is the principle of multithreaded downloading, but it is also necessary to record the size of each thread that has been downloaded after each pause, and the next download will be downloaded from the last download. In the general project, I will store the database. I simply exist in SharedPreferences for the sake of simplicity. I have downloaded URL and thread number as key value.

 @Override protected void onPostExecute (Long aLong) {Log.i (TAG, "download success"); / / / / / / / / / / / / / / record Downloaded the size current mSharedPreferences.edit ().PutLong ().PutLong (currentThreadIndex, current).Commit (); when the}

is downloaded, first gets the downloaded position, and if it has been downloaded, it begins to download from the location after the last download: download the saved information before the

 / / get, and end from the previous end. The location continues to be downloaded / / / / here file.exists () is added to determine whether the user has deleted it, if the file is not downloaded, but has been deleted by the user, then reloads long downedPosition = mSharedPreferences.getLong (currentThreadIndex, 0); if (file.exists () & & downedPosition! = 0) {) BeginPosition = beginPosition + downedPosition; current = downedPosition; synchronized (mCurrentLength) {mCurrentLength + = downedPosition;}}

= 1; / / / / download path. Nvironment.getExternalStorageDirectory () + File.separator + "download"; / / / private String mUrl = "http://ftp.neu.edu.cn/mirrors/eclipse/technology/epp/downloads/release/juno/SR2/eclipse-java-juno-SR2-linux-gtk-x86_64.tar.gz"; private String mUrl = "http://p.gdown.baidu.com/c4cb746699b92c9b6565c C65aa2e086552651f73c5d0e634a51f028e32af6abf3d68079eeb75401c76c9bb301e5fb71c144a704cb1a2f527a2e8ca3d6fe561dc5eaf6538e5b3ab0699308d13fe0b711a817c88b0f85a01a248df82824ace3cd7f2832c7c19173236 "; private ProgressBar mProgressBar; private TextView mPercentTV; SharedPreferences mSharedPreferences = null ; long mFileLength = 0; Long mCurrentLength = 0L; private InnerHandler mHandler = new InnerHandler (); / / / / / / create a thread pool private Executor. Ed void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); mProgressBar = (ProgressBar) findViewById. 'Context.MODE_PRIVATE'; / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / R.id.begin.SetOnClickListener (R.id.begin).SetOnClickListener (New View.OnClickListener () {@Override public void onClick (View V) {= {/ / / / / / / / / / / / / create storage folder]; If (! Dir.exists ()) {dir.mkdir ();} / / / / / obtain the file size HttpClient client = new DefaultHttpClient (); HttpGet request = new HttpGet (mUrl); Ty ().GetContentLength ();} catch (Exception E) {Log.e (TAG, e.getMessage ());} finally {if (request! = null) {} {};}};};}; / / suspend downloading. FindViewById (R.id.end).SetOnClickListener (New View.OnClickListener () {@Override public void onClick (View V) {for] }} mTaskList.clear ();}});} / * * * Download * according to the size of the file to be downloaded according to the size of the file to be downloaded, and create AsyncTask * / private void beginDownload () {mCurrentLength = 0L; mPercentTV.setVisibility (View.VISIBLE); mProgressBar.setProgress (0); long blockLen GTH = mFileLength / DEFAULT_POOL_SIZE; for (int i = 0; I < DEFAULT_POOL_SIZE; i++) {long beginPosition = = = > / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / i++) N = mFileLength; / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / if the entire file's size is not an integer multiple of the number of threads, the end of the last thread is the total length of the file} DownloadAsyncTask task = new DownloadAsyncTask (beginPosition, endPosition); mTaskList.add (task); task.executeOnExecutor (AsyncTask.THREAD_POOL_EXEC) UTOR, mUrl, String.valueOf (I));} / * * * / * * update progress bar * / synchronized public void updateProgress () {int percent = (int) Math.ceil. MProgressBar.getProgress ()) {mProgressBar.setProgress (percent); mPercentTV.setText ("download progress:" + percent + "%"); if (mProgressBar.getProgress () = = mProgressBar.getMax ()) {Toast.makeText (MainActivity.this, "download end", Toast.LENGTH_SHORT).Show ();}}}} Ected void onDestroy () {for (DownloadAsyncTask task: mTaskList) {if (task! = null & &) = = = = {} {};};} / * * / * * Download SyncTask< String, Integer, Long> {private static final String TAG = "DownloadAsyncTask"; private long) = 0; This.beginPosition = beginPosition; this.endPosition = endPosition;} @Override protected Long doInBackground (String... Params) {Log.i (TAG, "TAG,"); T = new DefaultHttpClient (); HttpGet request = new HttpGet (URL); HttpResponse response = null; InputStream. DexOf ("/") + 1))); / / / / / before downloading the saved information, continue downloading from the previous end and / / here to judge file.exists (), judge whether it is deleted by the user, if the file is not downloaded, but has been deleted by the user, then the long downedPosition = mSharedPreferences.getLo is reloaded. Ng (currentThreadIndex, 0); if (file.exists () & & downedPosition! = 0) {beginPosition = beginPosition + downedPosition; current = downedPosition; {} {{+ =} /} / / / / / / / / set downloaded data location Ion bytes to endPosition bytes Header header_size = new BasicHeader ("Range", "bytes=" + beginPosition + "-" + endPosition); request.addHeader (header_size); / / execution request


This concludes the body part