AsyncTask implements resumable upload and asynctask implements resumable upload.

Source: Internet
Author: User

AsyncTask implements resumable upload and asynctask implements resumable upload.

Previously, the project download module in the company was provided by xUtils. Recently, I read the source code of xUtils, which also uses AsyncTask to execute asynchronous tasks, its download also includes the resumable upload function. Here, I also use AsyncTask to implement a simple resumable upload function.

Let's talk about AsyncTask first. Let's take a look at the definition of AsyncTask:

1 public abstract class AsyncTask<Params, Progress, Result> 

The three generic types are "input parameters for starting task execution", "Progress of background task execution", and "type of background computing result ". In a specific scenario, not all types are used. If not, you can use the java. lang. Void type instead.

Generally, the execution of an asynchronous task includes the following steps:

1.Execute (Params... params)To execute an asynchronous task, we need to call this method in the code to trigger the execution of the asynchronous task.

2.OnPreExecute ()Execute (Params... params) immediately after being called. It is generally used to mark the UI before executing background tasks.

3.DoInBackground (Params... params), Which is executed immediately after onPreExecute () is completed for time-consuming operations. This method will receive input parameters and return calculation results. During execution, you can call publishProgress (Progress... values) to update the Progress information.

4.OnProgressUpdate (Progress... values)When publishProgress (Progress... values) is called, this method is executed and the Progress information is directly updated to the UI component.

5.OnPostExecute (Result result)When the background operation ends, this method will be called, and the calculation result will be passed as a parameter to this method, and the result will be directly displayed on the UI component.

Pay special attention to the following points:

1. the instance of the asynchronous task must be created in the UI thread.

2. The execute (Params... params) method must be called in the UI thread.

3. Do not manually call the onPreExecute (), doInBackground (Params... params), onProgressUpdate (Progress... values), onPostExecute (Result result) methods.

4. You cannot change the UI component information in doInBackground (Params... params.

5. A task instance can only be executed once. If it is executed for the second time, an exception is thrown.

The following code uses AsyncTask to implement resumable data transfer:

The idea of resumable upload is actually quite simple. First, determine whether the file to be downloaded exists locally. If yes, it indicates that the file has been downloaded, you only need to get the current file size, that is, the downloaded size. Set it to the http header:

1 Header header_size = new BasicHeader("Range", "bytes=" + readedSize + "-");2 request.addHeader(header_size);

 

1. layout file code:

1 <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" 2 xmlns: tools = "http://schemas.android.com/tools" android: layout_width = "match_parent" 3 android: layout_height = "match_parent" android: paddingLeft = "@ dimen/users" 4 android: paddingRight = "@ dimen/users" 5 android: paddingTop = "@ dimen/activity_vertical_margin" 6 android: paddingBottom = "@ dimen/ Activity_vertical_margin "tools: context = ". asyncTaskDemoActivity "7 android: orientation =" vertical "> 8 9 <Button10 android: id =" @ + id/begin "11 android: layout_width =" wrap_content "12 android: layout_height = "wrap_content" 13 android: text = "Start download"/> 14 15 <Button16 android: id = "@ + id/end" 17 android: layout_width = "wrap_content" 18 android: layout_height = "wrap_content" 19 android: text = "Pause download"/> 20 21 <ProgressBar22 android Oid: id = "@ + id/progressbar" 23 style = "? Android: attr/progressBarStyleHorizontal "24 android: layout_width =" fill_parent "25 android: layout_height =" 3dp "26 android: layout_marginTop =" 10dp "27 android: max = "100"/> 28 29 </LinearLayout>

The layout is relatively simple. There are two buttons and a progress bar control, and the buttons control the download and pause.

 

2. Core code for resumable upload:

1 package com. bbk. lling. myapplication; 2 3 import android. app. activity; 4 import android. OS. asyncTask; 5 import android. OS. bundle; 6 import android. OS. environment; 7 import android. util. log; 8 import android. view. view; 9 import android. widget. progressBar; 10 import android. widget. toast; 11 12 import org. apache. http. header; 13 import org. apache. http. httpResponse; 14 import org. apache. http. client. htt PClient; 15 import org. apache. http. client. methods. httpGet; 16 import org. apache. http. impl. client. defaultHttpClient; 17 import org. apache. http. message. basicHeader; 18 19 import java. io. file; 20 import java. io. fileOutputStream; 21 import java. io. IOException; 22 import java. io. inputStream; 23 import java. io. outputStream; 24 import java. io. randomAccessFile; 25 import java.net. malformedURLException; 26 27 public class AsyncTaskDemoActivity extends Activity {28 29 private ProgressBar progressBar; 30 // download path 31 private String downloadPath = Environment. getExternalStorageDirectory () + 32 File. separator + "download"; 33 private DownloadAsyncTask downloadTask; 34 35 @ Override 36 protected void onCreate (Bundle savedInstanceState) {37 super. onCreate (savedInstanceState); 38 setContentView (R. layout. act Ivity_async_task_demo); 39 progressBar = (ProgressBar) findViewById (R. id. progressbar); 40 // start to download 41 findViewById (R. id. begin ). setOnClickListener (new View. onClickListener () {42 @ Override 43 public void onClick (View v) {44/** 45 * an AsyncTask can only be executed once; otherwise, an exception 46 * java will be thrown. lang. illegalStateException: Cannot execute task: the task is already running. 47 * if you want to re-start the task, you need to re-create the AsyncTask object 48 */49 if (downloadTa Sk! = Null &&! DownloadTask. isCancelled () {50 return; 51} 52 downloadTask = new DownloadAsyncTask ("http://bbk-lewen.u.qiniudn.com/3d5b1a2c-4986-4e4a-a626-b504a36e600a.flv"); 53 downloadTask.exe cute (); 54} 55 }); 56 57 // pause download 58 findViewById (R. id. end ). setOnClickListener (new View. onClickListener () {59 @ Override 60 public void onClick (View v) {61 if (downloadTask! = Null & downloadTask. getStatus () = AsyncTask. status. RUNNING) {62 downloadTask. cancel (true); 63} 64} 65}); 66 67} 68 69/** 70 * downloaded AsyncTask 71 */72 private class DownloadAsyncTask extends AsyncTask <String, Integer, long> {73 private static final String TAG = "DownloadAsyncTask"; 74 private String mUrl; 75 76 public DownloadAsyncTask (String url) {77 this. mUrl = url; 78} 79 80 @ Override 81 protected Long doInBackground (String... params) {82 Log. I (TAG, "downloading"); 83 if (mUrl = null) {84 return null; 85} 86 HttpClient client = new DefaultHttpClient (); 87 HttpGet request = new HttpGet (mUrl); 88 HttpResponse response = null; 89 InputStream is = null; 90 RandomAccessFile fos = null; 91 OutputStream output = null; 92 93 try {94 // create a storage folder 95 File dir = new File (downloadPath); 9 6 if (! Dir. exists () {97 dir. mkdir (); 98} 99 // local File 100 file File = new File (downloadPath + File. separator + mUrl. substring (mUrl. lastIndexOf ("/") + 1); 101 if (! File. exists () {102 // create the file output stream 103 output = new FileOutputStream (file); 104 // get the download input stream 105 response = client.exe cute (request ); 106 is = response. getEntity (). getContent (); 107 // write 108 file locally. createNewFile (); 109 byte buffer [] = new byte [1024]; 110 int inputSize =-1; 111 // obtain the total file size, used to calculate the progress of 112 long total = response. getEntity (). getContentLength (); 113 int count = 0; // The downloaded size is 114 while (inputSize = is. read (buffer ))! =-1) {115 output. write (buffer, 0, inputSize); 116 count + = inputSize; 117 // Update Progress 118 this. publishProgress (int) (count/(float) total) * 100); 119 // exit the loop once the task is canceled; otherwise, it is executed continuously, until 120 if (isCancelled () {121 output. flush (); 122 return null; 123} 124} 125 output. flush (); 126} else {127 long readedSize = file. length (); // file size, that is, the downloaded size is 128. // you can specify the size of the downloaded data from XX bytes to 129 bytes. Header header_size = new BasicHeader ("Range", "byte S = "+ readedSize +"-"); 130 request. addHeader (header_size); 131 // execute the request to obtain the download input stream 132 response = client.exe cute (request); 133 is = response. getEntity (). getContent (); 134 // total file size = downloaded size + undownloaded size 135 long total = readedSize + response. getEntity (). getContentLength (); 136 137 // create a file output stream 138 fos = new RandomAccessFile (file, "rw"); 139 // write data from a location after the file size, in fact, you don't need to. You can simply write it later. Sometimes multi-thread download requires 140 fos. seek (readedSize); 141 // both RandomAccessFile and FileOutputStream can be used here, but the second brother parameter is required when FileOutputStream is used. true, 142 // output = new FileOutputStream (file, true); 143 144 1024 byte buffer [] = new byte [145]; int inputSize =-1; 146 int count = (int) readedSize; 147 while (inputSize = is. read (buffer ))! =-1) {148 fos. write (buffer, 0, inputSize); 149 // output. write (buffer, 0, inputSize); 150 count + = inputSize; 151 this. publishProgress (int) (count/(float) total) * 100); 152 if (isCancelled () {153 // output. flush (); 154 return null; 155} 156} 157 // output. flush (); 158} 159} catch (MalformedURLException e) {160 Log. e (TAG, e. getMessage (); 161} catch (IOException e) {162 Log. e (TAG, e. getMessage (); 1 63} finally {164 try {165 if (is! = Null) {166 is. close (); 167} 168 if (output! = Null) {169 output. close (); 170} 171 if (fos! = Null) {172 fos. close (); 173} 174} catch (Exception e) {175 e. printStackTrace (); 176} 177} 178 return null; 179} 180 181 @ Override182 protected void onPreExecute () {183 Log. (I (TAG, "download begin"); 184 Toast. makeText (AsyncTaskDemoActivity. this, "Start download", Toast. LENGTH_SHORT ). show (); 185 super. onPreExecute (); 186} 187 188 @ Override189 protected void onProgressUpdate (Integer... values) {190 super. onProgressUpdate (values); 191 Log. I (TAG, "downloading" + values [0]); 192 // update the interface progress bar 193 progressBar. setProgress (values [0]); 194} 195 196 @ Override197 protected void onPostExecute (Long aLong) {198 Log. I (TAG, "download success" + aLong); 199 Toast. makeText (AsyncTaskDemoActivity. this, "Download ended", Toast. LENGTH_SHORT ). show (); 200 super. onPostExecute (aLong); 201} 202} 203 204}

In this way, the simple resumable upload function is implemented. Here it is only for a single thread. If multiple threads are involved for simultaneous download, it is much more complicated and will be considered later.

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.