主Activity
public class MainActivity extends Activity { ListView listView; File cache; Handler handler = new Handler(){ public void handleMessage(Message msg) { //异步加载完后的图片数据集合 listView.setAdapter(new ContactAdapter(MainActivity.this, (List<Contact>)msg.obj, R.layout.listview_item, cache)); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView) this.findViewById(R.id.listView); //图片的缓存目录 cache = new File(Environment.getExternalStorageDirectory(), "cache"); if(!cache.exists()) cache.mkdirs(); new Thread(new Runnable() { public void run() { try { //加载的是名字和 图片URL信息 List<Contact> data = ContactService.getContacts(); handler.sendMessage(handler.obtainMessage(22, data)); } catch (Exception e) { e.printStackTrace(); } } }).start(); } @Override protected void onDestroy() { for(File file : cache.listFiles()){ file.delete(); } cache.delete(); super.onDestroy(); } }
内容服务类ContactService
1 public class ContactService { 2 3 /** 4 * 获取联系人 5 * @return 6 */ 7 public static List<Contact> getContacts() throws Exception{ 8 String path = "http://192.168.1.100:8080/web/list.xml"; 9 HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection(); 10 conn.setConnectTimeout(5000); 11 conn.setRequestMethod("GET"); 12 if(conn.getResponseCode() == 200){ 13 return parseXML(conn.getInputStream()); 14 } 15 return null; 16 } 17 18 private static List<Contact> parseXML(InputStream xml) throws Exception{ 19 20 List<Contact> contacts = new ArrayList<Contact>(); 21 Contact contact = null; 22 23 XmlPullParser pullParser = Xml.newPullParser(); 24 pullParser.setInput(xml, "UTF-8"); 25 int event = pullParser.getEventType(); 26 27 while(event != XmlPullParser.END_DOCUMENT){ 28 29 switch (event) { 30 case XmlPullParser.START_TAG: 31 32 if("contact".equals(pullParser.getName())){ 33 34 contact = new Contact(); 35 contact.id = new Integer(pullParser.getAttributeValue(0)); 36 37 }else if("name".equals(pullParser.getName())){ 38 contact.name = pullParser.nextText(); 39 40 }else if("image".equals(pullParser.getName())){ 41 contact.image = pullParser.getAttributeValue(0); 42 } 43 break; 44 45 case XmlPullParser.END_TAG: 46 if("contact".equals(pullParser.getName())){ 47 contacts.add(contact); 48 contact = null; 49 } 50 break; 51 } 52 event = pullParser.next(); 53 } 54 return contacts; 55 } 56 /** 57 * 获取网络图片,如果图片存在于缓存中,就返回该图片,否则从网络中加载该图片并缓存起来 58 * @param path 图片路径 59 * @return 60 */ 61 public static Uri getImage(String path, File cacheDir) throws Exception{// path -> MD5 ->32字符串.jpg 62 63 File localFile = new File(cacheDir, MD5.getMD5(path)+ path.substring(path.lastIndexOf("."))); 64 if(localFile.exists()){ 65 return Uri.fromFile(localFile); 66 }else{ 67 68 HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection(); 69 conn.setConnectTimeout(5000); 70 conn.setRequestMethod("GET"); 71 if(conn.getResponseCode() == 200){ 72 FileOutputStream outStream = new FileOutputStream(localFile); 73 InputStream inputStream = conn.getInputStream(); 74 byte[] buffer = new byte[1024]; 75 int len = 0; 76 while( (len = inputStream.read(buffer)) != -1){ 77 outStream.write(buffer, 0, len); 78 } 79 inputStream.close(); 80 outStream.close(); 81 return Uri.fromFile(localFile); 82 } 83 } 84 return null; 85 } 86 87 }
Adapter适配器
1 public class ContactAdapter extends BaseAdapter { 2 private List<Contact> data; 3 private int listviewItem; 4 private File cache; 5 LayoutInflater layoutInflater; 6 7 public ContactAdapter(Context context, List<Contact> data, int listviewItem, File cache) { 8 this.data = data; 9 this.listviewItem = listviewItem; 10 this.cache = cache; 11 layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 12 } 13 /** 14 * 得到数据的总数 15 */ 16 public int getCount() { 17 return data.size(); 18 } 19 /** 20 * 根据数据索引得到集合所对应的数据 21 */ 22 public Object getItem(int position) { 23 return data.get(position); 24 } 25 26 public long getItemId(int position) { 27 return position; 28 } 29 30 public View getView(int position, View convertView, ViewGroup parent) { 31 ImageView imageView = null; 32 TextView textView = null; 33 34 if(convertView == null){ 35 convertView = layoutInflater.inflate(listviewItem, null); 36 imageView = (ImageView) convertView.findViewById(R.id.imageView); 37 textView = (TextView) convertView.findViewById(R.id.textView); 38 convertView.setTag(new DataWrapper(imageView, textView)); 39 }else{ 40 DataWrapper dataWrapper = (DataWrapper) convertView.getTag(); 41 imageView = dataWrapper.imageView; 42 textView = dataWrapper.textView; 43 } 44 Contact contact = data.get(position); 45 textView.setText(contact.name); 46 asyncImageLoad(imageView, contact.image);//利用异步加载图片信息,传入图片URL 47 return convertView; 48 } 49 50 51 private void asyncImageLoad(ImageView imageView, String path) { 52 AsyncImageTask asyncImageTask = new AsyncImageTask(imageView); 53 asyncImageTask.execute(path); 54 55 } 56 57 private final class AsyncImageTask extends AsyncTask<String, Integer, Uri>{ 58 private ImageView imageView; 59 60 public AsyncImageTask(ImageView imageView) { 61 this.imageView = imageView; 62 } 63 protected Uri doInBackground(String... params) {//子线程中执行的 64 65 //如果图片存在于缓存中,就返回该图片,否则从网络中加载该图片并缓存起来 66 try { 67 return ContactService.getImage(params[0], cache); 68 } catch (Exception e) { 69 e.printStackTrace(); 70 } 71 return null; 72 } 73 74 protected void onPostExecute(Uri result) {//运行在主线程 75 if(result!=null && imageView!= null) 76 imageView.setImageURI(result); 77 } 78 } 79 80 private final class DataWrapper{ 81 public ImageView imageView; 82 public TextView textView; 83 84 public DataWrapper(ImageView imageView, TextView textView) { 85 this.imageView = imageView; 86 this.textView = textView; 87 } 88 } 89 }
MD5算法,根据路径生成MD5值
1 public class MD5 { 2 3 public static String getMD5(String content) { 4 try { 5 MessageDigest digest = MessageDigest.getInstance("MD5"); 6 digest.update(content.getBytes()); 7 return getHashString(digest); 8 9 } catch (NoSuchAlgorithmException e) { 10 e.printStackTrace(); 11 } 12 return null; 13 } 14 15 private static String getHashString(MessageDigest digest) { 16 StringBuilder builder = new StringBuilder(); 17 for (byte b : digest.digest()) { 18 builder.append(Integer.toHexString((b >> 4) & 0xf)); 19 builder.append(Integer.toHexString(b & 0xf)); 20 } 21 return builder.toString(); 22 } 23 }