功能如下:
流程如下:
RemoteImageViewActivity:
- public class RemoteImageViewActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- RemoteImageView img = (RemoteImageView) findViewById(R.id.remote_img);
- img.setDefaultImage(R.drawable.ic_launcher);
- img.setImageUrl("http://img2.kwcdn.kuwo.cn:81/star/albumcover/120/7/8/83787_1323997225.jpg");
- }
- @Override
- protected void onPause() {
- // TODO Auto-generated method stub
- super.onPause();
- }
- }
ImageCache:
- public class ImageCache extends WeakHashMap<String, Bitmap>{
- /**
- * 判断该url是否存在
- * @param url
- * @return
- */
- public boolean isCached(String url){
- return containsKey(url) && get(url) != null;
- }
- }
RemoteImageApplication:
- public class RemoteImageApplication extends Application {
- public static final String TAG = "RemoteImageApplication";
- private static RemoteImageApplication application;
- private ImageCache mImageCache;
- public SharedPreferences prefs = null;
- public static RemoteImageApplication getInstance() {
- return application;
- }
- @Override
- public void onCreate() {
- // TODO Auto-generated method stub
- super.onCreate();
- application = this;
- mImageCache = new ImageCache();
- prefs = PreferenceManager.getDefaultSharedPreferences(this);
- }
- public ImageCache getImageCache() {
- return mImageCache;
- }
- }
RemoteSettings:
- public class RemoteSettings {
- public static final String CACHE_SIZE = "cache_size"; //图片缓存保留大小,如果超过该大小,即进行自动清除缓存.
- }
RemoteImageView:
- public class RemoteImageView extends ImageView {
- private Context mContext;
- private static int mCacheSize = 150; // 设置的缓存大小。
- private static final int MAX_FAILURES = 3; // 下载的尝试请求次数
- private int mFailure; // 下载失败次数
- private String mUrl; // 当前下载的url
- private String mCurrentlyGrabbedUrl; // 当前下载成功的url
- private final static String JAMENDO_DIR = "Android/data/com.teleca.jamendo"; // 文件缓存存放的路径.
- private final static long MB = 1073741824;
- public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mContext = context;
- }
- public RemoteImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mContext = context;
- }
- public RemoteImageView(Context context) {
- super(context);
- mContext = context;
- }
- /**
- * 设置默认图片
- */
- public void setDefaultImage(Integer resid) {
- setImageResource(resid);
- }
- /**
- * 设置需要异步加载的图片
- */
- public void setImageUrl(String url) {
- // 下载失败进行重试,如果重试次数超过规定的限制,则直接返回.
- if (mUrl != null
- && mUrl.equals(url)
- && (mCurrentlyGrabbedUrl == null || (mCurrentlyGrabbedUrl != null && !mCurrentlyGrabbedUrl
- .equals(url)))) {
- mFailure++;
- if (mFailure > MAX_FAILURES) {
- Log.e(RemoteImageApplication.TAG, "下载该图片地址失败:" + url);
- return;
- }
- } else {
- mUrl = url;
- mFailure = 0;
- }
- ImageCache imageCache = RemoteImageApplication.getInstance()
- .getImageCache();
- if (imageCache.isCached(url)) {
- setImageBitmap(imageCache.get(url));
- } else {
- // 如果内存中没有该缓存,则从文件中进行查找.
- String fileName = convertUrlToFileName(url); // 进行文件名处理
- String filepath = getDirectory(fileName); // 取得缓存文件夹目录
- String pathFileName = filepath + "/" + fileName; // 组拼文件
- File pathFile = new File(pathFileName);
- if (!pathFile.exists()) {
- try {
- pathFile.createNewFile();
- } catch (IOException e) {
- Log.d(RemoteImageApplication.TAG, "创建图片文件失败:"
- + pathFileName);
- }
- }
- Bitmap tbmp = BitmapFactory.decodeFile(pathFileName);
- if (tbmp == null) {
- Log.d(RemoteImageApplication.TAG, "图片文件不存在,开始进行下载");
- try {
- new DownloadTask().execute(url);
- } catch (RejectedExecutionException e) {
- Log.d(RemoteImageApplication.TAG, "下载失败");
- }
- } else {
- Log.i(RemoteImageApplication.TAG, "从文件中加载图片");
- RemoteImageApplication.getInstance().getImageCache()
- .put(url, tbmp);
- this.setImageBitmap(tbmp);
- }
- updateCacheSize(pathFileName); // 进行检测文件大小,以便于清除缓存.
- }
- }
- private void updateCacheSize(String pathFileName) {
- // TODO Auto-generated method stub
- updateSizeCache(pathFileName);
- }
- /**
- * 检查文件目录是否超过规定的缓存大小
- *
- * @param fileName
- */
- private void updateSizeCache(String pathFileName) {
- // TODO Auto-generated method stub
- mCacheSize = PreferenceManager.getDefaultSharedPreferences(mContext)
- .getInt(RemoteSettings.CACHE_SIZE, 100); // 读取设置的缓存大小,前台可以动态设置此值
- if (isSDCardEnable()) {
- String extStorageDirectory = Environment
- .getExternalStorageDirectory().toString(); // 取得SD根路径
- String dirPath = extStorageDirectory + "/" + JAMENDO_DIR
- + "/imagecache";
- File dirFile = new File(dirPath);
- File[] files = dirFile.listFiles();
- long dirSize = 0;
- for (File file : files) {
- dirSize += file.length();
- }
- if (dirSize > mCacheSize * MB) {
- clearCache();
- }
- }
- }
- /**
- * 异步下载图片
- *
- * @ClassName: DownloadTask
- * @author 姜涛
- * @version 1.0 2012-1-15 下午5:06:21
- */
- class DownloadTask extends AsyncTask<String, Void, String> {
- private String mTaskUrl;
- private Bitmap mBmp = null;
- @Override
- public void onPreExecute() {
- // loadDefaultImage();
- super.onPreExecute();
- }
- @Override
- public String doInBackground(String... params) {
- mTaskUrl = params[0];
- InputStream stream = null;
- URL imageUrl;
- Bitmap bmp = null;
- try {
- imageUrl = new URL(mTaskUrl);
- try {
- stream = imageUrl.openStream();
- bmp = BitmapFactory.decodeStream(stream);
- try {
- if (bmp != null) {
- mBmp = bmp;
- RemoteImageApplication.getInstance()
- .getImageCache().put(mTaskUrl, bmp);
- Log.d(RemoteImageApplication.TAG,
- "图片缓存到application中: " + mTaskUrl);
- }
- } catch (NullPointerException e) {
- Log.w(RemoteImageApplication.TAG, "下载失败,图片为空:"
- + mTaskUrl);
- }
- } catch (IOException e) {
- Log.w(RemoteImageApplication.TAG, "无法加载该url:" + mTaskUrl);
- } finally {
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException e) {
- }
- }
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- return mTaskUrl;
- }
- @Override
- public void onPostExecute(String url) {
- super.onPostExecute(url);
- Bitmap bmp = RemoteImageApplication.getInstance().getImageCache()
- .get(url);
- if (bmp == null) {
- Log.w(RemoteImageApplication.TAG, "尝试重新下载:" + url);
- RemoteImageView.this.setImageUrl(url);
- } else {
- RemoteImageView.this.setImageBitmap(bmp);
- mCurrentlyGrabbedUrl = url;
- saveBmpToSd(mBmp, url);
- }
- }
- };
- /**
- * 把图片保存到本地
- *
- * @param bm
- * @param url
- */
- private void saveBmpToSd(Bitmap bm, String url) {
- if (bm == null) {
- return;
- }
- if (mCacheSize == 0) {
- return;
- }
- String filename = convertUrlToFileName(url);
- String dir = getDirectory(filename);
- File file = new File(dir + "/" + filename);
- try {
- file.createNewFile();
- OutputStream outStream = new FileOutputStream(file);
- bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
- outStream.flush();
- outStream.close();
- Log.i(RemoteImageApplication.TAG, "图片已保存到sd卡");
- } catch (FileNotFoundException e) {
- Log.w(RemoteImageApplication.TAG, "无法找到文件目录");
- } catch (IOException e) {
- Log.w(RemoteImageApplication.TAG, "操作文件出错");
- }
- }
- /**
- * 组拼文件名,后缀名用dat代替,避免别人使用图片管理器搜索出这种对于她们无用的图片.
- *
- * @param url
- * @return
- */
- private String convertUrlToFileName(String url) {
- String filename = url;
- filename = filename.replace("http://", "");
- filename = filename.replace("/", ".");
- filename = filename.replace(":", ".");
- filename = filename.replace("jpg", "dat");
- filename = filename.replace("png", "dat");
- return filename;
- }
- /**
- * 返回缓存图片所存放的文件夹
- *
- * @param filename
- * @return
- */
- private String getDirectory(String filename) {
- String extStorageDirectory = Environment.getExternalStorageDirectory()
- .toString(); // 取得SD根路径
- String dirPath = extStorageDirectory + "/" + JAMENDO_DIR
- + "/imagecache";
- File dirFile = new File(dirPath);
- if (!dirFile.exists()) {
- dirFile.mkdirs();
- }
- return dirPath;
- }
- /**
- * 清除缓存
- */
- private void clearCache() {
- if (isSDCardEnable()) {
- String extStorageDirectory = Environment
- .getExternalStorageDirectory().toString(); // 取得SD根路径
- String dirPath = extStorageDirectory + "/" + JAMENDO_DIR
- + "/imagecache";
- File dir = new File(dirPath);
- File[] files = dir.listFiles(); // 取得该目录下的所有文件
- if (files == null || files.length == 0) {
- return;
- }
- for (File file : files) {
- file.delete();
- }
- Log.d(RemoteImageApplication.TAG, "已清除缓存:" + dirPath);
- }
- }
- /**
- * 判断SD卡是否可用
- */
- public static boolean isSDCardEnable() {
- return Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED);
- }
- }