关于Android AsyncTask的一些总结
来源:互联网 发布:分级基金套利软件 编辑:程序博客网 时间:2024/06/14 08:20
根据Google自己的说法,AsyncTask只适用于数量不多且短暂的操作,至于原因嘛,可能是因为从Android 3.2开始,AsyncTask又被改成串行的了,这样如果你用AsyncTask执行很多任务,或者某个任务执行时间很长的话,那么后面的任务就没法及时执行了。下面先看它的一个典型用法,然后再具体展开说:
package com.whereru.testcode3;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.widget.ImageView;import android.widget.ProgressBar;import java.io.IOException;import java.io.InputStream;import java.lang.ref.WeakReference;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { private ImageView mImageView; private ProgressBar mProgressBar; private DownloadTask mDownloadTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); System.out.println("MainActivity onCreate"); mImageView = (ImageView) findViewById(R.id.image_view); mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); URL[] urls = null; try { urls = new URL[]{ new URL("http://img4.imgtn.bdimg.com/it/u=2317499888,864114656&fm=21&gp=0.jpg"), new URL("http://img0.imgtn.bdimg.com/it/u=4256573763,278547175&fm=21&gp=0.jpg"), new URL("http://img2.imgtn.bdimg.com/it/u=546811603,943746655&fm=21&gp=0.jpg"), new URL("http://img0.imgtn.bdimg.com/it/u=93040804,2971684664&fm=21&gp=0.jpg") }; } catch (MalformedURLException e) { e.printStackTrace(); } mDownloadTask = new DownloadTask(this); mDownloadTask.execute(urls); } @Override protected void onDestroy() { super.onDestroy(); mDownloadTask.cancel(false); System.out.println("MainActivity onDestroy"); } private static class DownloadTask extends AsyncTask<URL, Integer, List<Bitmap>> { private WeakReference<MainActivity> mMainActivityWeakReference; DownloadTask(MainActivity mainActivity) { mMainActivityWeakReference = new WeakReference<>(mainActivity); } @Override protected List<Bitmap> doInBackground(URL... urls) { //工作线程,负责下载图片,并转化成Bitmap HttpURLConnection httpURLConnection = null; List<Bitmap> bitmapList = new ArrayList<>(); for (int i = 0; i < urls.length; i++) { System.out.println("正在下载图片:" + (i + 1)); try { httpURLConnection = (HttpURLConnection) urls[i].openConnection(); InputStream inputStream = httpURLConnection.getInputStream(); if (httpURLConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new IOException(httpURLConnection.getResponseMessage() + ":with" + urls[i]); } bitmapList.add(BitmapFactory.decodeStream(inputStream)); } catch (IOException e) { e.printStackTrace(); } finally { if (httpURLConnection != null) { httpURLConnection.disconnect(); } } if (isCancelled()) { break; } publishProgress((int) (((float) (i + 1) / urls.length) * 100)); } return bitmapList; } @Override protected void onProgressUpdate(Integer... progress) { System.out.println("更新进度条"); if (mMainActivityWeakReference.get() != null) { mMainActivityWeakReference.get().mProgressBar.setProgress(progress[0]);//更新进度条 } } @Override protected void onPostExecute(final List<Bitmap> bitmapList) { System.out.println("图片下载完成,开始显示图片"); //图片下载完成后,在UI线程中每隔两秒显示一张图片 for (int i = 0; i < bitmapList.size(); i++) { final int finalI = i; new Handler().postDelayed(new Runnable() { @Override public void run() { if (mMainActivityWeakReference.get() != null) { mMainActivityWeakReference.get().mImageView .setImageBitmap(bitmapList.get(finalI)); } } }, 2000 * i); if (isCancelled()) { break; } } } }}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ProgressBar android:id="@+id/progress_bar" style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"/> <ImageView android:id="@+id/image_view" android:layout_width="300dp" android:layout_height="300dp"/></LinearLayout>
上面代码实现的功能就是从网上下载了4张图片,然后有个进度条可以显示下载进度,下载完成后,每隔两秒钟显示一张图片。
下面说下一些注意问题。
0.
如果你觉得Activity被销毁后就不需要相应AsyncTask接着执行任务了,记得在onDestroy中执行cancel方法。
1.
不管在你下载图片还是显示图片的for循环中记得用下:
if (isCancelled()) { break;}
这样可以确保在你取消相应任务的时候,可以及时停止接着做无用功。
2.
使用静态内部类和弱引用避免可能发生的内存泄露。(其实我觉得吧,其实如果内存不是很紧张,问题也不是很大,AsyncTask执行完了,自然Activity也就可以被回收了,而AsyncTask本来就不是用来执行长时间任务的,正常使用也不会长时间占着内存,个人看法。。。)
3.
考虑个问题,我们跳到了另一个Acyivity,然后我们并没有取消原来Activity的AsyncTask,而原来的Activity又被销毁了,会怎么样?
如果内存泄露的问题没解决,那程序肯定不会奔溃。那么采用了上面的方法解决了内存泄露,程序就一定会奔溃?其实也不一定,主要看那个被销毁的Activity是不是被GC回收了。不过为了安全起见,我们上面都做了WeakReference.get() != null的判断。
相关阅读:
Android多线程任务优化1:探讨AsyncTask的缺陷
- 关于Android AsyncTask的一些总结
- 关于android AsyncTask的相关问题总结
- 关于android的AsyncTask。
- 关于AsyncTask的Executor的一些研究
- android关于AsyncTask的分析
- Android关于图片读取的一些总结
- 关于android蓝牙开发的一些总结
- Android 关于ListView的一些小总结
- Android关于callback的一些总结
- 关于android生命周期的一些学习总结
- Android 关于内存泄漏的一些总结
- android 中asynctask的一些研究
- android AsyncTask相关的一些面试题目
- android中关于AsyncTask的学习
- Android中AsyncTask的简单总结
- Android 异步任务 AsyncTask 的使用总结
- Android初学习 - AsyncTask的用法总结
- 关于Android Context一些总结
- 技术随笔 五 —— 心中的马
- 永久开启完整版Google Play
- linux 下svn 命令详解
- C++ 递归和非递归实现链表逆序
- Scala:内部类
- 关于Android AsyncTask的一些总结
- C7_结构体
- MFC全屏
- python打开浏览器指定网页并填写内容---微信篇
- [转]使用handler时的warning:ThisHandlerclassshouldbestaticorleaksmightoccur
- iOS中自定义视图控件
- USACO Milking Cows(模拟)
- 类的三大特性之封装、继承
- C7_结构体多文件