android 使用AsyncTask实现异步下载文件
16lz
2021-01-24
android中的异步方法也很多,之前一直使用Handler+Thread的方法,今天学习了AsyncTask,来实现耗时操作:从网络下载文件。
AsyncTask定义了三种泛型类型Params,Progress和Result。
我们使用AsyncTask实现4个常用的方法来完成相应的功能,如下:
(1) doInBackground: 子线程中运行,耗时操作。将执行结束的结果返回onPostExecute()参数中
(2) onPreExecute: 运行在UI线程中,任务执行前的准备
(3) onPostExecute: 运行在UI线程中,处理异步线程的任务结果
(4) onProgressUpdate: 运行在UI线程中,更新当前进度条信息,被publishProgress回调
DownFileActivity :
public class DownFileActivity extends Activity implements View.OnClickListener { /* SD卡根目录 */ private File rootDie; /* 输出文件名称 */ private String outFileName = "ldjfh.jar"; /* 进度条对话框 */ private ProgressDialog pdialog; private MyLoadAsyncTask myLoadAsyncTask = new MyLoadAsyncTask(); @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.downfile); checkAndCreateDir(); getPermission();//动态获取权限 findViewById(R.id.file_download_btn).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.file_download_btn) {/* 异步下载 */ myLoadAsyncTask.execute("http://192.168");//有效的URL地址 } } //AsyncTask是基于线程池进行实现的,当一个线程没有结束时,后面的线程是不能执行的. @Override protected void onDestroy() { super.onDestroy(); if (myLoadAsyncTask != null && myLoadAsyncTask.getStatus() == AsyncTask.Status.RUNNING) { //cancel方法只是将对应的AsyncTask标记为cancelt状态,并不是真正的取消线程的执行. myLoadAsyncTask.cancel(true); } } @Override protected Dialog onCreateDialog(int id) {/* 实例化进度条对话框 */ pdialog = new ProgressDialog(this);/* 进度条对话框属性设置 */ pdialog.setMessage("正在下载中...");/* 进度值最大100 */ pdialog.setMax(100);/* 水平风格进度条 */ pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);/* 无限循环模式 */ pdialog.setIndeterminate(false);/* 可取消 */ pdialog.setCancelable(true);/* 显示对话框 */ pdialog.show(); return pdialog; } /* 检查sdcard并创建目录文件 */ private void checkAndCreateDir() {/* 获取sdcard目录 */ rootDie = Environment.getExternalStorageDirectory();/* 新文件的目录 */ File newFile = new File(rootDie + "/download1/"); if (!newFile.exists()) {/* 如果文件不存在就创建目录 */ newFile.mkdirs(); } } /** * 动态获取权限 */ private void getPermission() { PackageManager pm = getPackageManager(); boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.WRITE_EXTERNAL_STORAGE", "com.zhengyuan.learningserverdownloadfile")); if (permission) { Toast.makeText(DownFileActivity.this, "有权限", Toast.LENGTH_SHORT).show(); } else { //版本高于6.0 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.INTERNET}, 12); } } //申请权限 } /* 异步任务,后台处理与更新UI */ class MyLoadAsyncTask extends AsyncTask { /* 后台线程 */ @Override protected String doInBackground(String... params) { /* 所下载文件的URL */ try { URL url = new URL(params[0]); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); /* URL属性设置 */ conn.setRequestMethod("GET"); /* URL建立连接 */ conn.connect(); /* 下载文件的大小 */ int fileOfLength = conn.getContentLength(); /* 每次下载的大小与总下载的大小 */ int totallength = 0; int length = 0; /* 输入流 */ InputStream in = conn.getInputStream(); /* 输出流 */ FileOutputStream out = new FileOutputStream(new File(rootDie + "/download1/", outFileName)); /* 缓存模式,下载文件 */ byte[] buff = new byte[1024 * 1024]; while ((length = in.read(buff)) > 0) { totallength += length; String str1 = "" + (int) ((totallength * 100) / fileOfLength); publishProgress(str1); out.write(buff, 0, length); }/* 关闭输入输出流 */ in.close(); out.flush(); out.close(); } catch (MalformedURLException e) {// TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace(); } return null; } /* 预处理UI线程 */ @Override protected void onPreExecute() { showDialog(0); super.onPreExecute(); } /* 结束时的UI线程 */ @Override protected void onPostExecute(String result) { dismissDialog(0); super.onPostExecute(result); } /* 处理UI线程,会被多次调用,触发事件为publicProgress方法 */ @Override protected void onProgressUpdate(String... values) { /* 进度显示 */ pdialog.setProgress(Integer.parseInt(values[0])); } }}
downfile.xml:
<?xml version="1.0" encoding="utf-8"?>
有时候我们需要activity结束后,下载也结束,但是因为是后台运行,即时activity结束后,文件还是会被下载下来。
我们在onDestroy添加如下代码
@Override protected void onDestroy() { super.onDestroy(); if (myLoadAsyncTask != null && myLoadAsyncTask.getStatus() == AsyncTask.Status.RUNNING) { //cancel方法只是将对应的AsyncTask标记为cancelt状态,并不是真正的取消线程的执行. myLoadAsyncTask.cancel(true); } }
当然AsyncTask还有跟多的功能需要学习,在网上找到一个比较好的博客。
http://www.cnblogs.com/liuling/p/2015-10-10-01.html
更多相关文章
- android通过更改hosts免优酷广告方法
- 如何优雅的避免android(安卓)运行时崩溃
- android 热修复之类加载机制
- cordova操作Android本地文件系统
- [android] HttpURLConnection的初步学习
- Adapter
- Android(安卓)中Message,MessageQueue,Looper,Handler详解+实例
- Android(安卓)实现歌词同步
- Chrome V8 引擎移植到 Android