Android下实现图片缓存的实例
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.imagecache"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.imagecache.CacheImageTestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package com.example.imagecache; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class CacheImageTestActivity extends Activity { private ImageView img_01; private ImageView img_02; private ImageView img_03; private ImageView img_04; private Button btn_test; private CacheImageUtils utils = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); utils = new CacheImageUtils(); findControls(); initControls(); } private void initControls() { btn_test.setOnClickListener(new OnTestClickListener()); } private void findControls() { img_01 = (ImageView) findViewById(R.id.aiv_imgview_01); img_02 = (ImageView) findViewById(R.id.aiv_imgview_02); img_03 = (ImageView) findViewById(R.id.aiv_imgview_03); img_04 = (ImageView) findViewById(R.id.aiv_imgview_04); btn_test = (Button) findViewById(R.id.aiv_btn_test); } class OnTestClickListener implements OnClickListener { @Override public void onClick(View arg0) { String downloadUrl_01 = new String( "http://www.doyoojob.com/Javascript/jqueryPackage/easyslider1.7/images/01.jpg"); utils.setImageDownloadable(downloadUrl_01, img_01); /* String downloadUrl_02 = new String( "http://imgsrc.baidu.com/forum/pic/item/4d086e061d950a7bcec82e790ad162d9f3d3c98a.jpg"); utils.setImageDownloadable(downloadUrl_02, img_02); String downloadUrl_03 = new String( "http://imgsrc.baidu.com/forum/pic/item/3b87e950352ac65ceebe31d5fbf2b21192138ad9.jpg"); utils.setImageDownloadable(downloadUrl_03, img_03); String downloadUrl_04 = new String( "http://imgsrc.baidu.com/forum/pic/item/ca1349540923dd5416c9f0ced109b3de9d8248d9.jpg"); utils.setImageDownloadable(downloadUrl_04, img_04);*/ } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
package com.example.imagecache; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.os.Environment; public class Downloader { private static final int BUF_SIZE = 4096; private static String downloadPath = Environment.getExternalStorageDirectory().toString()+ File.separator + "mycache"; /** * 设置下载路径,如/sdcard/cache的形式,不带反斜线; * * @param downloadPath */ public static void setDownloadPath(String downloadPath) { Downloader.downloadPath = downloadPath; } /** * 通过下载地址得到文件名 * * @param downloadUrl * @return */ private static String getShortFileName(String downloadUrl) { int lastSlashIndex = downloadUrl.lastIndexOf(File.separator); if (-1 == lastSlashIndex) return ""; return downloadUrl.substring(lastSlashIndex + 1); } /** * 通过下载地址和本地下载目录得到文件名的绝对路径 * * @param downloadUrl * @return */ public static String getFullFileName(String downloadUrl) { String shortFileName = getShortFileName(downloadUrl); if ("".equals(shortFileName)) return ""; return downloadPath + File.separator + shortFileName; } /** * 下载指定url文件 * * @param downloadUrl * @return * @throws IOException */ public static String downloadFile(String downloadUrl) throws IOException { String fullFileName = getFullFileName(downloadUrl); if ("".equals(fullFileName)) throw new IOException("下载地址错误"); // 如果目录不存在,创建目录 File folder = new File(downloadPath); if ((!folder.exists()) || (!folder.isDirectory())) if (!folder.mkdirs()) throw new IOException("目录创建失败!"); // 如果文件存在,直接返回文件名;不存在的话创建文件 File file = new File(fullFileName); if (file.exists()) return fullFileName; if (!file.exists()) if (!file.createNewFile()) throw new IOException("文件创建失败!"); // 下载内容写入输入流 URL url = new URL(downloadUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); InputStream ins = null; int respCode = conn.getResponseCode(); if (respCode == 200) { ins = conn.getInputStream(); } else { throw new IOException("获取内容错误,错误代码:" + respCode); } if (null == ins) throw new IOException("下载流为空!"); // 将输入流转换写入文件 FileOutputStream outs = new FileOutputStream(file); int readsize = 0; byte[] buffer = new byte[BUF_SIZE]; while ((readsize = ins.read(buffer)) != -1) { outs.write(buffer, 0, readsize); } outs.close(); ins.close(); conn.disconnect(); return fullFileName; } }
package com.example.imagecache; import java.io.File; import java.io.IOException; import java.util.HashMap; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.widget.ImageView; public class CacheImageUtils { private static HashMap<String, String> filemap = new HashMap<String, String>(); private boolean isFileNameValid(String fullFileName) { if ((null == fullFileName) || ("".equals(fullFileName))) return false; else return true; } public void setImageDownloadable(final String downloadUrl, final ImageView v) { String fullFileName = null; // 如果已经有链接地址/文件记录,直接取得文件名;否则获取文件名 if (filemap.containsKey(downloadUrl)) { fullFileName = filemap.get(downloadUrl); } else { System.out.println("Downloader------------>"); fullFileName = Downloader.getFullFileName(downloadUrl); } // 如果文件名不合法,直接退出 if (!isFileNameValid(fullFileName)) return; // 文件有效,直接显示 final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { String fullFileName = (String) msg.obj; Drawable drawable = Drawable.createFromPath(fullFileName); v.setImageDrawable(drawable); } }; Thread downloadThread = new Thread() { @Override public void run() { String fullFileName = Downloader.getFullFileName(downloadUrl); try { fullFileName = Downloader.downloadFile(downloadUrl); if (isFileNameValid(fullFileName)) filemap.put(downloadUrl, fullFileName); Message msg = handler.obtainMessage(0, fullFileName); handler.sendMessage(msg); } catch (IOException e) { e.printStackTrace(); // 发生异常的时候删除文件 if (isFileNameValid(fullFileName)) { File file = new File(fullFileName); if (file.exists()) file.delete(); } // 发生异常的时候删除对应关系 if (filemap.containsKey(downloadUrl)) filemap.remove(downloadUrl); } } }; downloadThread.start(); } }
很容易忘记:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>