AsyncTask类可以实现异步操作,通过其接口可以实现在子线程实现网络下载请求,并可返回结果在UI线程操作结果
public class DownloadAsync extends AsyncTask<String, Integer, Boolean>
AsyncTask定义了三种泛型类型参数 Params,Progress和Result。分别对应上面的String Integer Boolean
1.Params 启动任务执行的输入参数,比如HTTP请求的URL。
2.Progress 后台任务执行的百分比。这里的结果返回的是可变参数 Integer
会传入到
protected void onProgressUpdate(Integer... values)
可以用来对进度更新等操作
3.Result 后台执行任务最终返回的结果,比如这里返回的是Boolean。
protected void onPostExecute(Boolean aBoolean)
这里做的效果图如下:
之后再FileManager中可以看到下载的apk文件:
、
具体代码实现如下:
建立的DownloadHelper类封装了AsyncTask类
public class DownloadHelper {
public static void Download(String url, String path, onDownloadListener listener){
DownloadAsync task = new DownloadAsync(url, path, listener);
task.execute();
}
public static class DownloadAsync extends AsyncTask<String, Integer, Boolean> {
String mUrl;
String mPath;
onDownloadListener mOnDownloadListener;
static int contentLength;
public DownloadAsync(String url, String path, onDownloadListener listener) {
mUrl = url;
mPath = path;
mOnDownloadListener = listener;
}
/**
* 通过主线程调用execute(String ..)执行
* (子线程)
*/
@Override
protected Boolean doInBackground(String... params) {
try {
/**
* 执行下载任务
*/
URL url = new URL(mUrl);
URLConnection con = url.openConnection();
InputStream is = con.getInputStream();
//下载总长度
contentLength = con.getContentLength();
File apkFile = new File(mPath);
if(apkFile.exists()){
if(!apkFile.delete()){
if(mOnDownloadListener != null){
mOnDownloadListener.onFail(-2, apkFile, "文件删除失败");
}
}
}
// 已下载长度
int downloadLength = 0;
byte[] bytes = new byte[1024];
int len;
OutputStream os = new FileOutputStream(mPath);
while ((len = is.read(bytes)) >-1 ){
os.write(bytes, 0, len);
downloadLength += len;
//传入两个参数到onProgressUpdate(Integer... values)
publishProgress(downloadLength * 100 / contentLength
, downloadLength);
}
is.close();
os.close();
} catch (MalformedURLException e) {
e.printStackTrace();
if(mOnDownloadListener != null){
mOnDownloadListener.onFail(-2, new File(mPath), e.getMessage());
}
return false;
} catch (IOException e) {
e.printStackTrace();
if(mOnDownloadListener != null){
mOnDownloadListener.onFail(-3, new File(mPath), e.getMessage());
}
return false;
}
return true;
}
/**
* 请求之前的操作调用了接口
* 的onStart方法(UI线程)
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
if(mOnDownloadListener != null){
mOnDownloadListener.onStart();
}
}
/**
* 请求之后的操作,判断了doInBackground返回值Boolean类型调用了接口
* 的onSuccess(UI线程)
*/
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if(aBoolean){
if(mOnDownloadListener != null){
mOnDownloadListener.onSuccess(0, new File(mPath));
}
}else{
}
}
/**
* 在doInBackground中调用的publishProgress会将其参数传入
* @Integer类型可变参数,用于更新进度条及下载进度(UI线程)
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(values == null || values.length == 0) {
return ;
}
if(mOnDownloadListener != null){
mOnDownloadListener.onProgress(values[0], values[1]);
}
}
}
//自定义接口用于实现请求成功,失败,进度,开始的处理
public interface onDownloadListener {
void onSuccess(int code, File file);
void onFail(int code, File file, String msg);
void onProgress(int progress, int downloadLength);
void onStart();
}
}
DownloadActivity如下
public class DownloadActivity extends AppCompatActivity {
private static final String FILE_NAME = "i999.apk";
private static final String TAG = "DownloadActivity";
private ProgressBar progressBar;
private TextView resultText;
private Button downloadButton;
private final static String APK_URL = "http://www.imooc.com/mobile/mukewang.apk";
private final static String FILE_PATH = Environment.getExternalStorageDirectory()
+ File.separator + FILE_NAME;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
initView();
bindEvents();
}
private void initView() {
progressBar = (ProgressBar) findViewById(R.id.progressBar);
resultText = (TextView) findViewById(R.id.result_txt);
downloadButton = (Button) findViewById(R.id.download_btn);
}
private void bindEvents() {
downloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//传入参数1.URL 2.下载路径 3.接口(实现请求的各种处理)
DownloadHelper.Download(APK_URL, FILE_PATH, new DownloadHelper.onDownloadListener() {
@Override
public void onSuccess(int code, File file) {
downloadButton.setText(R.string.waiting);
downloadButton.setEnabled(true);
resultText.setText(getString(R.string.download_finish));
}
@Override
public void onFail(int code, File file, String msg) {
downloadButton.setText(R.string.waiting);
downloadButton.setEnabled(true);
resultText.setText(getString(R.string.download_fail));
}
@Override
public void onProgress(int progress, int downloadLength) {
progressBar.setProgress(progress);
resultText.setText(downloadLength + "/" + DownloadHelper.DownloadAsync.contentLength);
}
@Override
public void onStart() {
downloadButton.setText(R.string.begin);
downloadButton.setEnabled(false);
}
});
}
});
}
}
有些时候可能我们并不需要实现onStart ,onProgress方法。所以我们可以在接口中定义一个抽象类如下图:
如下图: