使用AsyncTask下载远端资源到SD卡

本文介绍了一个用于Android平台的下载组件实现细节,包括如何利用AsyncTask进行后台下载操作并实时更新UI,展示了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下载远端资源,需要INTERNET权限;
将文件写入到SD,需要WRITE_EXTERNAL_STORAGE权限;

在AndroidManifest.xml中进行如下配置:

?
1
2
< uses-permission android:name = "android.permission.INTERNET" />
< uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />

Android AsyncTask提供了简单易用的方式,执行后台操作并更新UI。

AsyncTask的3个泛型

• Param  传入数据类型
• Progress  更新UI数据类型
• Result  处理结果类型

AsyncTask的4个步骤

1、onPreExecute  执行前的操作
2、doInBackGround  后台执行的操作
3、onProgressUpdate  更新UI操作
4、onPostExecute  执行后的操作

从网络下载资源到SD卡的步骤:

1、HTTP请求资源InputStream
2、在SD中创建一个空文件
3、创建该文件的FileOutputStream
4、使用while循环,InputStream每次循环读入数据到字节数组buffer中(buffer字节数组的大小一般为1024的整数倍),FileOutputStream将buffer中的数据写入文件,直到EOF,read()方法返回-1

示例代码:
功能:下载网络资源到本地

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package lizhen.download;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
 
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
 
import android.os.AsyncTask;
 
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
 
     protected int size;
     protected String errorMessage;
 
     @Override
     protected Boolean doInBackground(String... params) {
         String url = params[ 0 ]; // 资源地址
         String path = params[ 1 ]; // 目标路径
         try {
             InputStream source = requestInputStream(url); // 请求源文件InputStream
             /**
              * 创建文件写入数据,并更新进度
              */
             fileWrite(source, path, new OnProgressUpdateListener() {
 
                 @Override
                 public void onProgressUpdate( int progress) {
                     publishProgress(progress);
                 }
             });
 
         } catch (ClientProtocolException e) {
             errorMessage = e.getMessage();
             cancel( true );
             return false ;
         } catch (IOException e) {
             errorMessage = e.getMessage();
             cancel( true );
             return false ;
         }
         return true ;
     }
 
     /**
      * 文件写入
      *
      * @param in
      *            数据源输出流
      * @param path
      *            文件路径
      * @param listener
      *            下载进度监听器
      * */
     private void fileWrite(InputStream in, String path,
             OnProgressUpdateListener listener) throws IOException {
         File file = createFile(path);
         FileOutputStream fileOutputStream = new FileOutputStream(file);
         byte buffer[] = new byte [ 1024 ];
         int progress = 0 ;
         int readBytes = 0 ;
         while ((readBytes = in.read(buffer)) != - 1 ) {
             progress += readBytes;
             fileOutputStream.write(buffer, 0 , readBytes);
             if (listener != null ) {
                 listener.onProgressUpdate(progress);
             }
         }
         in.close();
         fileOutputStream.close();
     }
 
     /**
      * 下载进度监听器
      * */
     private interface OnProgressUpdateListener {
         /**
          * 下载进度更新
          *
          * @param progress
          *            进度
          * */
         public void onProgressUpdate( int progress);
     }
 
     /**
      * 根据资源URL地址取得资源输入流
      *
      * @param url
      *            URL地址
      * @return 资源输入流
      * @throws ClientProtocolException
      * @throws IOException
      * */
     private InputStream requestInputStream(String url)
             throws ClientProtocolException, IOException {
         InputStream result = null ;
         HttpGet httpGet = new HttpGet(url);
         HttpClient httpClient = new DefaultHttpClient();
         HttpResponse httpResponse = httpClient.execute(httpGet);
         int httpStatusCode = httpResponse.getStatusLine().getStatusCode();
         if (httpStatusCode == HttpStatus.SC_OK) {
             HttpEntity httpEntity = httpResponse.getEntity();
             size = ( int ) httpEntity.getContentLength();
             result = httpEntity.getContent();
         }
         return result;
     }
 
     /**
      * 根据文件路径创建文件
      *
      * @param path
      *            文件路径
      * @return 文件File实例
      * @return IOException
      * */
     private File createFile(String path) throws IOException {
         File file = new File(path);
         file.createNewFile();
         return file;
     }
 
     /**
      * 返回错误信息
      *
      * @return 错误信息
      * */
     public String getErrorString() {
         return this .errorMessage;
     }
 
}

功能:用户界面,更新进度条和下载进度,显示下载图片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package lizhen.download;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
 
public class Download extends Activity {
 
     private Button startButton;
     private ProgressBar downloadProgressBar;
     private TextView progressTextView;
     private ImageView downloadImageView;
 
     private final String source = "http://www.android-study.com/resource/atm.gif" ; // 源文件地址
     private final String path = Environment.getExternalStorageDirectory()
             .toString() + "/atm.gif" ; // 目标文件地址
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.download);
 
         startButton = (Button) findViewById(R.id.download_StartButton);
         downloadProgressBar = (ProgressBar) findViewById(R.id.download_ProgressBar);
         progressTextView = (TextView) findViewById(R.id.download_ProgressTextView);
         downloadImageView = (ImageView) findViewById(R.id.download_ImageView);
 
         startButton.setOnClickListener( new View.OnClickListener() {
 
             @Override
             public void onClick(View v) {
                 new DownloadTask().execute(source, path);
             }
         });
     }
 
     private class DownloadTask extends DownloadAsyncTask {
 
         @Override
         protected void onProgressUpdate(Integer... values) {
             super .onProgressUpdate(values);
             int progress = values[ 0 ];
             /*
              * 更新进度条和下载百分率
              */
             downloadProgressBar.setMax(size);
             downloadProgressBar.setProgress(progress);
             int percentage = progress * 100 / size;
             progressTextView.setText( "已完成" + percentage + "%" );
         }
 
         @Override
         protected void onPostExecute(Boolean result) {
             super .onPostExecute(result);
             if (result) {
                 Bitmap bitmap = BitmapFactory.decodeFile(path);
                 downloadImageView.setImageBitmap(bitmap);
             } else {
                 Toast.makeText(Download. this , "Error: " + errorMessage, 1000 )
                         .show();
             }
         }
     }
}

运行结果:

远程下载效果图


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值