android上的一个网络接口和图片缓存框架enif

来源:互联网 发布:疯狂追星 知乎 编辑:程序博客网 时间:2024/04/30 17:34

1.底层网络接口采用apache的httpclient连接池框架;

2.图片缓存采用基于LRU的算法;

3.网络接口采用监听者模式;

4.包含图片的OOM处理(及时回收处理技术的应用);

 

图片核心处理类:CacheView.java

[java] view plaincopy
  1. package xiaogang.enif.image;  
  2.   
  3. import java.io.FilterInputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.lang.ref.SoftReference;  
  7. import java.util.HashMap;  
  8. import java.util.concurrent.RejectedExecutionException;  
  9.   
  10. import org.apache.http.HttpEntity;  
  11. import org.apache.http.HttpResponse;  
  12. import org.apache.http.HttpStatus;  
  13. import org.apache.http.client.methods.HttpGet;  
  14.   
  15. import xiaogang.enif.utils.HttpManager;  
  16. import xiaogang.enif.utils.IOUtils;  
  17. import xiaogang.enif.utils.LogUtils;  
  18. import xiaogang.enif.utils.LruCache;  
  19. import android.app.ActivityManager;  
  20. import android.content.Context;  
  21. import android.graphics.Bitmap;  
  22. import android.graphics.BitmapFactory;  
  23. import android.graphics.BitmapFactory.Options;  
  24. import android.graphics.Canvas;  
  25. import android.graphics.drawable.BitmapDrawable;  
  26. import android.os.AsyncTask;  
  27. import android.text.TextUtils;  
  28. import android.util.AttributeSet;  
  29. import android.widget.ImageView;  
  30.   
  31. public class CacheView extends ImageView {  
  32.     private static final int DEFAULT_RES_ID = 0;  
  33.     private int mDefaultImage = DEFAULT_RES_ID;  
  34.   
  35.     private static LruCache<String, Bitmap> mLruCache;  
  36.     private static HashMap<Integer, SoftReference<Bitmap>> mResImage;  
  37.   
  38.     private Context mContext;  
  39.     private LogUtils mLog = LogUtils.getLog(CacheView.class);  
  40.   
  41.     public CacheView(Context context, AttributeSet attrs, int defStyle) {  
  42.         super(context, attrs, defStyle);  
  43.         init(context);  
  44.     }  
  45.   
  46.     public CacheView(Context context, AttributeSet attrs) {  
  47.         super(context, attrs);  
  48.         init(context);  
  49.   
  50.     }  
  51.   
  52.     public CacheView(Context context) {  
  53.         super(context);  
  54.         init(context);  
  55.     }  
  56.   
  57.     private void init(Context context) {  
  58.         mContext = context;  
  59.   
  60.         if (mLruCache == null) {  
  61.             final int cacheSize = getCacheSize(context);  
  62.             mLruCache = new LruCache<String, Bitmap>(cacheSize) {  
  63.                 @Override  
  64.                 protected int sizeOf(String key, Bitmap bitmap) {  
  65.                     // The cache size will be measured in bytes rather than  
  66.                     // number of items.  
  67.                     return bitmap.getRowBytes() * bitmap.getHeight();  
  68.                 }  
  69.   
  70.                 @Override  
  71.                 protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,  
  72.                         Bitmap newValue) {  
  73.                     if (evicted && oldValue != null && !oldValue.isRecycled()) {  
  74.                         oldValue.recycle();  
  75.                         oldValue = null;  
  76.                     }  
  77.                 }  
  78.             };  
  79.         }  
  80.   
  81.         if (mResImage == null) {  
  82.             mResImage = new HashMap<Integer, SoftReference<Bitmap>>();  
  83.         }  
  84.     }  
  85.   
  86.     @Override  
  87.     protected void onDraw(Canvas canvas) {  
  88.         BitmapDrawable drawable = (BitmapDrawable)getDrawable();  
  89.         if (drawable == null) {  
  90.             setDefaultImage();  
  91.         } else {  
  92.             if (drawable.getBitmap() == null || drawable.getBitmap().isRecycled()) {  
  93.                 setDefaultImage();  
  94.             }  
  95.         }  
  96.         try {  
  97.             super.onDraw(canvas);  
  98.         } catch(RuntimeException ex) {  
  99.   
  100.         }  
  101.     }  
  102.   
  103.     public void setImageUrl(String url, int resId) {  
  104.         setTag(url);  
  105.         Bitmap bitmap = getBitmapFromCache(url);  
  106.         if (bitmap == null || bitmap.isRecycled()) {  
  107.             mDefaultImage = resId;  
  108.             setDefaultImage();  
  109.             try {  
  110.                 new DownloadTask().execute(url);  
  111.             } catch (RejectedExecutionException e) {  
  112.                 // do nothing, just keep not crash  
  113.             }  
  114.         } else {  
  115.             setImageBitmap(bitmap);  
  116.         }  
  117.     }  
  118.   
  119.     private void setDefaultImage() {  
  120.         if (mDefaultImage != DEFAULT_RES_ID) {  
  121.             setImageBitmap(getDefaultBitmap(mContext));  
  122.         }  
  123.     }  
  124.   
  125.     private Bitmap getDefaultBitmap(Context context) {  
  126.         SoftReference<Bitmap> loading = mResImage.get(mDefaultImage);  
  127.         if (loading == null || loading.get() == null || loading.get().isRecycled()) {  
  128.             loading = new SoftReference<Bitmap>(BitmapFactory.decodeResource(  
  129.                     context.getResources(), mDefaultImage));  
  130.             mResImage.put(mDefaultImage, loading);  
  131.         }  
  132.         return loading.get();  
  133.     }  
  134.   
  135.     private class DownloadTask extends AsyncTask<String, Void, Bitmap> {  
  136.         private String mParams;  
  137.   
  138.         @Override  
  139.         public Bitmap doInBackground(String... params) {  
  140.             mParams = params[0];  
  141.             final Bitmap bm = download(mParams);  
  142.             addBitmapToCache(mParams, bm);  
  143.             return bm;  
  144.         }  
  145.   
  146.         @Override  
  147.         public void onPostExecute(Bitmap bitmap) {  
  148.             String tag = (String)getTag();  
  149.             if (!TextUtils.isEmpty(tag) && tag.equals(mParams)) {  
  150.                 if (bitmap != null) {  
  151.                     setImageBitmap(bitmap);  
  152.                 }  
  153.             }  
  154.         }  
  155.     };  
  156.   
  157.     /* 
  158.      * An InputStream that skips the exact number of bytes provided, unless it 
  159.      * reaches EOF. 
  160.      */  
  161.     static class FlushedInputStream extends FilterInputStream {  
  162.         public FlushedInputStream(InputStream inputStream) {  
  163.             super(inputStream);  
  164.         }  
  165.   
  166.         @Override  
  167.         public long skip(long n) throws IOException {  
  168.             long totalBytesSkipped = 0L;  
  169.             while (totalBytesSkipped < n) {  
  170.                 long bytesSkipped = in.skip(n - totalBytesSkipped);  
  171.                 if (bytesSkipped == 0L) {  
  172.                     int b = read();  
  173.                     if (b < 0) {  
  174.                         break// we reached EOF  
  175.                     } else {  
  176.                         bytesSkipped = 1// we read one byte  
  177.                     }  
  178.                 }  
  179.                 totalBytesSkipped += bytesSkipped;  
  180.             }  
  181.             return totalBytesSkipped;  
  182.         }  
  183.     }  
  184.   
  185.     private Bitmap download(String url) {  
  186.         InputStream in = null;  
  187.         HttpEntity entity = null;  
  188.         Bitmap bmp = null;  
  189.         try {  
  190.             final HttpGet get = new HttpGet(url);  
  191.             final HttpResponse response = HttpManager.execute(mContext, get);  
  192.             if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  193.                 entity = response.getEntity();  
  194.                 in = entity.getContent();  
  195.                 try {  
  196.                     bmp = getDecodeBitmap(in, url);  
  197.                 } catch (OutOfMemoryError err) {  
  198.                     Runtime.getRuntime().gc();  
  199.                     bmp = getDecodeBitmap(in, url);  
  200.                 }  
  201.             } else {  
  202.                 get.abort();  
  203.                 return bmp;  
  204.             }  
  205.             addBitmapToCache(url, bmp);  
  206.         } catch (IOException e) {  
  207.             return bmp;  
  208.         } finally {  
  209.             IOUtils.closeStream(in);  
  210.         }  
  211.         return bmp;  
  212.     }  
  213.   
  214.     private final Bitmap getDecodeBitmap(InputStream in, String url) {  
  215.         Options options = new Options();  
  216.         options.inPurgeable = true;  
  217.         options.inInputShareable = true;  
  218.         return BitmapFactory.decodeStream(new FlushedInputStream(in), null, options);  
  219.     }  
  220.   
  221.     private final void addBitmapToCache(String url, Bitmap bitmap) {  
  222.         if (bitmap != null) {  
  223.             mLruCache.put(url, bitmap);  
  224.             Runtime.getRuntime().gc();  
  225.         }  
  226.     }  
  227.   
  228.     private final Bitmap getBitmapFromCache(String url) {  
  229.         return mLruCache.get(url);  
  230.     }  
  231.   
  232.     private int getCacheSize(Context context) {  
  233.         // According to the phone memory, set a proper cache size for LRU cache  
  234.         // dynamically.  
  235.         final ActivityManager am = (ActivityManager)context  
  236.                 .getSystemService(Context.ACTIVITY_SERVICE);  
  237.         final int memClass = am.getMemoryClass();  
  238.   
  239.         int cacheSize;  
  240.         if (memClass <= 24) {  
  241.             cacheSize = (memClass << 20) / 24;  
  242.         } else if (memClass <= 36) {  
  243.             cacheSize = (memClass << 20) / 18;  
  244.         } else if (memClass <= 48) {  
  245.             cacheSize = (memClass << 20) / 12;  
  246.         } else {  
  247.             cacheSize = (memClass << 20) >> 3;  
  248.         }  
  249.         mLog.debug("cacheSize == "+cacheSize);  
  250.         System.out.println("cacheSize == "+cacheSize);  
  251.         return cacheSize;  
  252.     }  
  253.   
  254.     public static void recycle() {  
  255.         if (mLruCache != null && !mLruCache.isEmpty()) {  
  256.             mLruCache.evictAll();  
  257.             mLruCache = null;  
  258.         }  
  259.   
  260.         if (mResImage != null) {  
  261.             for (SoftReference<Bitmap> reference : mResImage.values()) {  
  262.                 Bitmap bitmap = reference.get();  
  263.                 if (bitmap != null && !bitmap.isRecycled()) {  
  264.                     bitmap.recycle();  
  265.                     bitmap = null;  
  266.                 }  
  267.             }  
  268.             mResImage = null;  
  269.         }  
  270.     }  
  271. }  


说明:

1)entryRemoved在做bitmap recycle的时候的3个条件缺一不可;

2)onDraw里面判断图片是否被回收,如果回收,需要设置默认图片;

3)add bitmap到cache的时候Runtime.getRuntime().gc();的调用;

4)getCacheSize可以根据手机具体的内存来动态设置我们实际需要的缓存大小;

5)退出时,记得调用recycle()方法;

 

网络接口核心类:WSAPI.java, WSCfg.java, WSTask.java

[java] view plaincopy
  1. <strong>package xiaogang.enif.net;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import org.apache.http.message.BasicNameValuePair;  
  6.   
  7. /** 
  8.  * web service configuration file 
  9.  * */  
  10. public class WSCfg {  
  11.     public static final int USER_LOGIN = 0;//action  
  12.     public static final int USER_LOGOUT = 1;//action  
  13.   
  14.     public static ArrayList<BasicNameValuePair> sValuePairs;//common vps  
  15.   
  16.     static {  
  17.         sValuePairs = new ArrayList<BasicNameValuePair>();  
  18.         sValuePairs.add(new BasicNameValuePair("v""1.0"));  
  19.         sValuePairs.add(new BasicNameValuePair("format""json"));  
  20.     }  
  21.   
  22. }</strong>  
[java] view plaincopy
  1. <strong>package xiaogang.enif.net;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.concurrent.RejectedExecutionException;  
  5.   
  6. import org.apache.http.message.BasicNameValuePair;  
  7.   
  8. import xiaogang.enif.net.WSTask.TaskListener;  
  9. import android.content.Context;  
  10.   
  11. public class WSAPI {  
  12.     private WSAPI() {  
  13.   
  14.     }  
  15.   
  16.     public static void execute(Context context, TaskListener listener, int action,  
  17.             ArrayList<BasicNameValuePair> vp) {  
  18.         try {  
  19.             new WSTask(context, listener, action, vp).execute();  
  20.         } catch (RejectedExecutionException e) {  
  21.             // do nothing, just keep not crashing.  
  22.         }  
  23.     }  
  24. }  
  25. </strong>  

 

[java] view plaincopy
  1. <strong>package xiaogang.enif.net;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.util.ArrayList;  
  6. import java.util.HashMap;  
  7. import java.util.Iterator;  
  8.   
  9. import org.apache.http.HttpEntity;  
  10. import org.apache.http.HttpResponse;  
  11. import org.apache.http.HttpStatus;  
  12. import org.apache.http.client.entity.UrlEncodedFormEntity;  
  13. import org.apache.http.client.methods.HttpPost;  
  14. import org.apache.http.message.BasicNameValuePair;  
  15. import org.json.JSONArray;  
  16. import org.json.JSONException;  
  17. import org.json.JSONObject;  
  18.   
  19. import xiaogang.enif.utils.HttpManager;  
  20. import xiaogang.enif.utils.IOUtils;  
  21. import xiaogang.enif.utils.LogUtils;  
  22. import android.app.Activity;  
  23. import android.content.Context;  
  24. import android.os.AsyncTask;  
  25. import android.text.TextUtils;  
  26.   
  27. public class WSTask extends AsyncTask<Void, Void, Object> {  
  28.     private int mAction;  
  29.     private String mErrorCode;  
  30.     private Object mParameter;  
  31.   
  32.     private Context mContext;  
  33.     private TaskListener mTaskListener;  
  34.     private Exception mReason;  
  35.     private final LogUtils mLog = LogUtils.getLog(WSTask.class);  
  36.   
  37.     public WSTask(Context context, TaskListener listener, int action, Object paramObject) {  
  38.         mContext = context;  
  39.         mTaskListener = listener;  
  40.         mParameter = paramObject;  
  41.         mAction = action;  
  42.     }  
  43.   
  44.     @Override  
  45.     public Object doInBackground(Void... arg0) {  
  46.         Object result = null;  
  47.         try {  
  48.             @SuppressWarnings("unchecked")  
  49.             ArrayList<BasicNameValuePair> vps = (ArrayList<BasicNameValuePair>)mParameter;  
  50.             final String jsonString = request(mContext, "your url", vps);  
  51.             mLog.debug(jsonString);  
  52.             result = parseJson(jsonString);  
  53.             if (result != null && result instanceof String  
  54.                     && TextUtils.isDigitsOnly((String)result)) {  
  55.                 mErrorCode = (String)result;  
  56.                 return null;  
  57.             }  
  58.         } catch (Exception e) {  
  59.             mReason = e;  
  60.             mLog.error(e.getMessage());  
  61.             return null;  
  62.         }  
  63.   
  64.         return result;  
  65.     }  
  66.   
  67.     @Override  
  68.     public void onPostExecute(Object result) {  
  69.         if (mContext== null) {  
  70.             clearTask();  
  71.             return;  
  72.         }  
  73.   
  74.         if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) {  
  75.             clearTask();  
  76.             return;  
  77.         }  
  78.   
  79.         if (result == null || mReason != null) {  
  80.             mTaskListener.onFailed(mAction, mErrorCode, mReason);  
  81.         } else {  
  82.             mTaskListener.onSuccess(mAction, result);  
  83.         }  
  84.         clearTask();  
  85.     }  
  86.   
  87.     private String request(Context context, String url, ArrayList<BasicNameValuePair> vp)  
  88.             throws IOException {  
  89.         final HttpPost post = new HttpPost(url);  
  90.         post.setEntity(new UrlEncodedFormEntity(vp, "UTF_8"));  
  91.   
  92.         InputStream in = null;  
  93.         HttpEntity entity = null;  
  94.         try {  
  95.             final HttpResponse response = HttpManager.execute(context, post);  
  96.             final int statusCode = response.getStatusLine().getStatusCode();  
  97.             if (statusCode == HttpStatus.SC_OK) {  
  98.                 entity = response.getEntity();  
  99.                 if (entity != null) {  
  100.                     in = entity.getContent();  
  101.                     return IOUtils.stream2String(in);  
  102.                 }  
  103.             } else {  
  104.                 post.abort();  
  105.                 mLog.error("http code: " + response.getStatusLine().getStatusCode());  
  106.             }  
  107.             return null;  
  108.         } catch (IOException ex) {  
  109.             post.abort();  
  110.             throw ex;  
  111.         } catch (RuntimeException ex) {  
  112.             post.abort();  
  113.             throw ex;  
  114.         } finally {  
  115.             if(entity!=null) {  
  116.                 entity.consumeContent();  
  117.             }  
  118.             IOUtils.closeStream(in);  
  119.         }  
  120.     }  
  121.   
  122.     private Object parseJson(String jsonString) throws IOException {  
  123.         try {  
  124.             JSONObject jobj = new JSONObject(jsonString);  
  125.             if (jobj.has("errorcode")) {  
  126.                 return jobj.optString("errorcode");  
  127.             }  
  128.   
  129.             if (jobj.has("resultlist")) {  
  130.                 ArrayList<HashMap<String, String>> arrList;  
  131.                 arrList = new ArrayList<HashMap<String, String>>();  
  132.                 JSONArray jsonArray = jobj.optJSONArray("resultlist");  
  133.                 final int len = jsonArray.length();  
  134.                 for (int i = 0; i < len; i++) {  
  135.                     final JSONObject obj = (JSONObject)jsonArray.opt(i);  
  136.                     arrList.add(parse2Map(obj));  
  137.                 }  
  138.                 return arrList;  
  139.             } else {  
  140.                 return parse2Map(jobj);  
  141.             }  
  142.         } catch (JSONException e) {  
  143.             IOException ioe = new IOException("Invalid json String...");  
  144.             ioe.initCause(e);  
  145.             throw ioe;  
  146.         }  
  147.     }  
  148.   
  149.     private HashMap<String, String> parse2Map(JSONObject jsonObj) throws IOException {  
  150.         final HashMap<String, String> hashMap = new HashMap<String, String>();  
  151.         @SuppressWarnings("unchecked")  
  152.         final Iterator<String> keyIter = jsonObj.keys();  
  153.         String key, value;  
  154.         while (keyIter != null && keyIter.hasNext()) {  
  155.             key = keyIter.next();  
  156.             value = jsonObj.optString(key);  
  157.             hashMap.put(key, value);  
  158.         }  
  159.         return hashMap;  
  160.     }  
  161.   
  162.     private void clearTask() {  
  163.         mTaskListener = null;  
  164.         mParameter = null;  
  165.         mContext = null;  
  166.     }  
  167.   
  168.     public interface TaskListener {  
  169.         public void onSuccess(int action, Object result);  
  170.         public void onFailed(int action, String errcode, Exception ex);  
  171.     }  
  172. }  
  173. </strong>  


说明:

1)根据你的服务器接口实际情况,去修改parseJson方法;

2)WSCfg里面可以定义接口的action;

sample:

[java] view plaincopy
  1. package xiaogang.enif.ui;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import org.apache.http.message.BasicNameValuePair;  
  6.   
  7. import xiaogang.enif.R;  
  8. import xiaogang.enif.image.CacheView;  
  9. import xiaogang.enif.net.WSAPI;  
  10. import xiaogang.enif.net.WSCfg;  
  11. import xiaogang.enif.net.WSTask.TaskListener;  
  12. import xiaogang.enif.widget.ListsApdater;  
  13. import android.app.Activity;  
  14. import android.os.Bundle;  
  15. import android.widget.ListView;  
  16.   
  17. public class MainActivity extends Activity implements TaskListener {  
  18.     ListView mList;  
  19.     ListsApdater mAdapter;  
  20.   
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main);  
  25.         setupViews();  
  26.     }  
  27.   
  28.     private void setupViews() {  
  29.         mList = (ListView)findViewById(R.id.list);  
  30.         mAdapter = new ListsApdater(this, mUrls);  
  31.         mList.setAdapter(mAdapter);  
  32.         final ArrayList<BasicNameValuePair> vp = new ArrayList<BasicNameValuePair>();  
  33.         vp.addAll(WSCfg.sValuePairs);  
  34.         vp.add(new BasicNameValuePair("imei""123"));  
  35.         vp.add(new BasicNameValuePair("imsi""123"));  
  36.         WSAPI.execute(thisthis, WSCfg.USER_LOGIN, vp);  
  37.     }  
  38.   
  39.     @Override  
  40.     protected void onDestroy() {  
  41.         super.onDestroy();  
  42.         mAdapter.recycle();  
  43.         CacheView.recycle();  
  44.     }  
  45.   
  46.     private String[] mUrls = {  
  47.             "http://a3.twimg.com/profile_images/670625317/aam-logo-v3-twitter.png",  
  48.             "http://a3.twimg.com/profile_images/740897825/AndroidCast-350_normal.png",  
  49.             "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",  
  50.             "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",  
  51.             "http://a1.twimg.com/profile_images/97470808/icon_normal.png",  
  52.             "http://a3.twimg.com/profile_images/511790713/AG.png",  
  53.             "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",  
  54.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  55.             "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",  
  56.             "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",  
  57.             "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",  
  58.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  59.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",  
  60.             "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",  
  61.             "http://a1.twimg.com/profile_images/655119538/andbook.png",  
  62.             "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",  
  63.             "http://a1.twimg.com/profile_images/74724754/android_logo_normal.png",  
  64.             "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",  
  65.             "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",  
  66.             "http://a3.twimg.com/profile_images/548410609/icon_8_73.png",  
  67.             "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",  
  68.             "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",  
  69.             "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_android_normal.png",  
  70.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  71.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",  
  72.             "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",  
  73.             "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",  
  74.             "http://a3.twimg.com/profile_images/511790713/AG_normal.png",  
  75.             "http://a3.twimg.com/profile_images/956404323/androinica-avatar.png",  
  76.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  77.             "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",  
  78.             "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",  
  79.             "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",  
  80.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  81.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",  
  82.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  83.             "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300.jpg",  
  84.             "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",  
  85.             "http://a3.twimg.com/profile_images/511790713/AG_normal.png",  
  86.             "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",  
  87.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  88.             "http://a3.twimg.com/profile_images/121630227/Droid.jpg",  
  89.             "http://a1.twimg.com/profile_images/97470808/icon_normal.png",  
  90.             "http://a3.twimg.com/profile_images/511790713/AG_normal.png",  
  91.             "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",  
  92.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man.png",  
  93.             "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",  
  94.             "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",  
  95.             "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",  
  96.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  97.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",  
  98.             "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",  
  99.             "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",  
  100.             "http://a1.twimg.com/profile_images/97470808/icon.png",  
  101.             "http://a3.twimg.com/profile_images/511790713/AG_normal.png",  
  102.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  103.             "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",  
  104.             "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",  
  105.             "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",  
  106.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  107.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",  
  108.             "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",  
  109.             "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",  
  110.             "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",  
  111.             "http://a1.twimg.com/profile_images/74724754/android_logo.png",  
  112.             "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",  
  113.             "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",  
  114.             "http://a3.twimg.com/profile_images/548410609/icon_8_73_normal.png",  
  115.             "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",  
  116.             "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",  
  117.             "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_android.png",  
  118.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  119.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",  
  120.             "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",  
  121.             "http://a1.twimg.com/profile_images/655119538/andbook.png",  
  122.             "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",  
  123.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  124.             "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",  
  125.             "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",  
  126.             "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",  
  127.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  128.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",  
  129.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  130.             "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",  
  131.             "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",  
  132.             "http://a3.twimg.com/profile_images/511790713/AG_normal.png",  
  133.             "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",  
  134.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  135.             "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",  
  136.             "http://a1.twimg.com/profile_images/957149154/twitterhalf.jpg",  
  137.             "http://a1.twimg.com/profile_images/97470808/icon_normal.png",  
  138.             "http://a3.twimg.com/profile_images/511790713/AG_normal.png",  
  139.             "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",  
  140.             "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",  
  141.             "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",  
  142.             "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",  
  143.             "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png"  
  144.     };  
  145.   
  146.     @Override  
  147.     public void onSuccess(int action, Object result) {  
  148.         switch (action) {  
  149.             case WSCfg.USER_LOGIN:  
  150.                 break;  
  151.             case WSCfg.USER_LOGOUT:  
  152.                 break;  
  153.         }  
  154.     }  
  155.   
  156.     @Override  
  157.     public void onFailed(int action, String errcode, Exception ex) {  
  158.         switch (action) {  
  159.             case WSCfg.USER_LOGIN:  
  160.                 break;  
  161.             case WSCfg.USER_LOGOUT:  
  162.                 break;  
  163.         }  
  164.     }  
  165. }  

 

[java] view plaincopy
  1. package xiaogang.enif.widget;  
  2.   
  3. import xiaogang.enif.R;  
  4. import xiaogang.enif.image.CacheView;  
  5. import android.content.Context;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.TextView;  
  11.   
  12. public class ListsApdater extends BaseAdapter {  
  13.     private String[] mUrls;  
  14.     private LayoutInflater mInflater;  
  15.   
  16.     public ListsApdater(Context context, String[] urls) {  
  17.         mUrls = urls;  
  18.         mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  19.     }  
  20.   
  21.     @Override  
  22.     public int getCount() {  
  23.         return mUrls.length;  
  24.     }  
  25.   
  26.     @Override  
  27.     public Object getItem(int position) {  
  28.         return position;  
  29.     }  
  30.   
  31.     @Override  
  32.     public long getItemId(int position) {  
  33.         return position;  
  34.     }  
  35.   
  36.     @Override  
  37.     public View getView(int position, View convertView, ViewGroup parent) {  
  38.         ViewHolder holder = null;  
  39.         if (null == convertView) {  
  40.             holder = new ViewHolder();  
  41.             convertView = mInflater.inflate(R.layout.item, null);  
  42.             holder.view = (CacheView)convertView.findViewById(R.id.image);  
  43.             holder.text = (TextView)convertView.findViewById(R.id.text);  
  44.             convertView.setTag(holder);  
  45.         } else {  
  46.             holder = (ViewHolder)convertView.getTag();  
  47.         }  
  48.   
  49.         holder.text.setText("item "+position);  
  50.         holder.view.setImageUrl(mUrls[position], R.drawable.stub);  
  51.         return convertView;  
  52.     }  
  53.   
  54.     public void recycle() {  
  55.         mUrls = null;  
  56.         mInflater = null;  
  57.     }  
  58.   
  59.     private class ViewHolder {  
  60.         CacheView view;  
  61.         TextView text;  
  62.     }  
  63. }  


main.xml和item.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <ListView  
  8.         android:id="@+id/list"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="0dip"  
  11.         android:layout_weight="1" />  
  12.   
  13. </LinearLayout>  

 

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content" >  
  5.   
  6.     <xiaogang.enif.image.CacheView  
  7.         android:id="@+id/image"  
  8.         android:layout_width="50dip"  
  9.         android:layout_height="50dip"  
  10.         android:scaleType="centerCrop"  
  11.         android:src="@drawable/stub" />  
  12.   
  13.     <TextView  
  14.         android:id="@+id/text"  
  15.         android:layout_width="0dip"  
  16.         android:layout_height="wrap_content"  
  17.         android:layout_gravity="left|center_vertical"  
  18.         android:layout_marginLeft="10dip"  
  19.         android:layout_weight="1"  
  20.         android:textSize="20dip" />  
  21.   
  22. </LinearLayout>  

例子的效果图如下:





完整例子代码详见:http://code.google.com/p/enif/

或者 http://download.csdn.net/detail/androidzhaoxiaogang/4797109 

 

 


原创粉丝点击