网络 图片缓存

引用:http://blog.csdn.net/androidzhaoxiaogang/article/details/8211649

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

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

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

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

图片核心处理类:CacheView.java

  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. }  
package xiaogang.enif.image;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.concurrent.RejectedExecutionException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;

import xiaogang.enif.utils.HttpManager;
import xiaogang.enif.utils.IOUtils;
import xiaogang.enif.utils.LogUtils;
import xiaogang.enif.utils.LruCache;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.ImageView;

public class CacheView extends ImageView {
    private static final int DEFAULT_RES_ID = 0;
    private int mDefaultImage = DEFAULT_RES_ID;

    private static LruCache<String, Bitmap> mLruCache;
    private static HashMap<Integer, SoftReference<Bitmap>> mResImage;

    private Context mContext;
    private LogUtils mLog = LogUtils.getLog(CacheView.class);

    public CacheView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public CacheView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);

    }

    public CacheView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        mContext = context;

        if (mLruCache == null) {
            final int cacheSize = getCacheSize(context);
            mLruCache = new LruCache<String, Bitmap>(cacheSize) {
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    // The cache size will be measured in bytes rather than
                    // number of items.
                    return bitmap.getRowBytes() * bitmap.getHeight();
                }

                @Override
                protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
                        Bitmap newValue) {
                    if (evicted && oldValue != null && !oldValue.isRecycled()) {
                        oldValue.recycle();
                        oldValue = null;
                    }
                }
            };
        }

        if (mResImage == null) {
            mResImage = new HashMap<Integer, SoftReference<Bitmap>>();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        BitmapDrawable drawable = (BitmapDrawable)getDrawable();
        if (drawable == null) {
            setDefaultImage();
        } else {
            if (drawable.getBitmap() == null || drawable.getBitmap().isRecycled()) {
                setDefaultImage();
            }
        }
        try {
            super.onDraw(canvas);
        } catch(RuntimeException ex) {

        }
    }

    public void setImageUrl(String url, int resId) {
        setTag(url);
        Bitmap bitmap = getBitmapFromCache(url);
        if (bitmap == null || bitmap.isRecycled()) {
            mDefaultImage = resId;
            setDefaultImage();
            try {
                new DownloadTask().execute(url);
            } catch (RejectedExecutionException e) {
                // do nothing, just keep not crash
            }
        } else {
            setImageBitmap(bitmap);
        }
    }

    private void setDefaultImage() {
        if (mDefaultImage != DEFAULT_RES_ID) {
            setImageBitmap(getDefaultBitmap(mContext));
        }
    }

    private Bitmap getDefaultBitmap(Context context) {
        SoftReference<Bitmap> loading = mResImage.get(mDefaultImage);
        if (loading == null || loading.get() == null || loading.get().isRecycled()) {
            loading = new SoftReference<Bitmap>(BitmapFactory.decodeResource(
                    context.getResources(), mDefaultImage));
            mResImage.put(mDefaultImage, loading);
        }
        return loading.get();
    }

    private class DownloadTask extends AsyncTask<String, Void, Bitmap> {
        private String mParams;

        @Override
        public Bitmap doInBackground(String... params) {
            mParams = params[0];
            final Bitmap bm = download(mParams);
            addBitmapToCache(mParams, bm);
            return bm;
        }

        @Override
        public void onPostExecute(Bitmap bitmap) {
            String tag = (String)getTag();
            if (!TextUtils.isEmpty(tag) && tag.equals(mParams)) {
                if (bitmap != null) {
                    setImageBitmap(bitmap);
                }
            }
        }
    };

    /*
     * An InputStream that skips the exact number of bytes provided, unless it
     * reaches EOF.
     */
    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break; // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

    private Bitmap download(String url) {
        InputStream in = null;
        HttpEntity entity = null;
        Bitmap bmp = null;
        try {
            final HttpGet get = new HttpGet(url);
            final HttpResponse response = HttpManager.execute(mContext, get);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                entity = response.getEntity();
                in = entity.getContent();
                try {
                    bmp = getDecodeBitmap(in, url);
                } catch (OutOfMemoryError err) {
                    Runtime.getRuntime().gc();
                    bmp = getDecodeBitmap(in, url);
                }
            } else {
                get.abort();
                return bmp;
            }
            addBitmapToCache(url, bmp);
        } catch (IOException e) {
            return bmp;
        } finally {
            IOUtils.closeStream(in);
        }
        return bmp;
    }

    private final Bitmap getDecodeBitmap(InputStream in, String url) {
        Options options = new Options();
        options.inPurgeable = true;
        options.inInputShareable = true;
        return BitmapFactory.decodeStream(new FlushedInputStream(in), null, options);
    }

    private final void addBitmapToCache(String url, Bitmap bitmap) {
        if (bitmap != null) {
            mLruCache.put(url, bitmap);
            Runtime.getRuntime().gc();
        }
    }

    private final Bitmap getBitmapFromCache(String url) {
        return mLruCache.get(url);
    }

    private int getCacheSize(Context context) {
        // According to the phone memory, set a proper cache size for LRU cache
        // dynamically.
        final ActivityManager am = (ActivityManager)context
                .getSystemService(Context.ACTIVITY_SERVICE);
        final int memClass = am.getMemoryClass();

        int cacheSize;
        if (memClass <= 24) {
            cacheSize = (memClass << 20) / 24;
        } else if (memClass <= 36) {
            cacheSize = (memClass << 20) / 18;
        } else if (memClass <= 48) {
            cacheSize = (memClass << 20) / 12;
        } else {
            cacheSize = (memClass << 20) >> 3;
        }
        mLog.debug("cacheSize == "+cacheSize);
        System.out.println("cacheSize == "+cacheSize);
        return cacheSize;
    }

    public static void recycle() {
        if (mLruCache != null && !mLruCache.isEmpty()) {
            mLruCache.evictAll();
            mLruCache = null;
        }

        if (mResImage != null) {
            for (SoftReference<Bitmap> reference : mResImage.values()) {
                Bitmap bitmap = reference.get();
                if (bitmap != null && !bitmap.isRecycled()) {
                    bitmap.recycle();
                    bitmap = null;
                }
            }
            mResImage = null;
        }
    }
}


说明:

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

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

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

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

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

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

  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>  
package xiaogang.enif.net;

import java.util.ArrayList;

import org.apache.http.message.BasicNameValuePair;

/**
 * web service configuration file
 * */
public class WSCfg {
    public static final int USER_LOGIN = 0;//action
    public static final int USER_LOGOUT = 1;//action

    public static ArrayList<BasicNameValuePair> sValuePairs;//common vps

    static {
        sValuePairs = new ArrayList<BasicNameValuePair>();
        sValuePairs.add(new BasicNameValuePair("v", "1.0"));
        sValuePairs.add(new BasicNameValuePair("format", "json"));
    }

}
  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>  
package xiaogang.enif.net;

import java.util.ArrayList;
import java.util.concurrent.RejectedExecutionException;

import org.apache.http.message.BasicNameValuePair;

import xiaogang.enif.net.WSTask.TaskListener;
import android.content.Context;

public class WSAPI {
    private WSAPI() {

    }

    public static void execute(Context context, TaskListener listener, int action,
            ArrayList<BasicNameValuePair> vp) {
        try {
            new WSTask(context, listener, action, vp).execute();
        } catch (RejectedExecutionException e) {
            // do nothing, just keep not crashing.
        }
    }
}
  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>  
package xiaogang.enif.net;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import xiaogang.enif.utils.HttpManager;
import xiaogang.enif.utils.IOUtils;
import xiaogang.enif.utils.LogUtils;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.text.TextUtils;

public class WSTask extends AsyncTask<Void, Void, Object> {
    private int mAction;
    private String mErrorCode;
    private Object mParameter;

    private Context mContext;
    private TaskListener mTaskListener;
    private Exception mReason;
    private final LogUtils mLog = LogUtils.getLog(WSTask.class);

    public WSTask(Context context, TaskListener listener, int action, Object paramObject) {
        mContext = context;
        mTaskListener = listener;
        mParameter = paramObject;
        mAction = action;
    }

    @Override
    public Object doInBackground(Void... arg0) {
        Object result = null;
        try {
            @SuppressWarnings("unchecked")
            ArrayList<BasicNameValuePair> vps = (ArrayList<BasicNameValuePair>)mParameter;
            final String jsonString = request(mContext, "your url", vps);
            mLog.debug(jsonString);
            result = parseJson(jsonString);
            if (result != null && result instanceof String
                    && TextUtils.isDigitsOnly((String)result)) {
                mErrorCode = (String)result;
                return null;
            }
        } catch (Exception e) {
            mReason = e;
            mLog.error(e.getMessage());
            return null;
        }

        return result;
    }

    @Override
    public void onPostExecute(Object result) {
        if (mContext== null) {
            clearTask();
            return;
        }

        if (mContext instanceof Activity && ((Activity) mContext).isFinishing()) {
            clearTask();
            return;
        }

        if (result == null || mReason != null) {
            mTaskListener.onFailed(mAction, mErrorCode, mReason);
        } else {
            mTaskListener.onSuccess(mAction, result);
        }
        clearTask();
    }

    private String request(Context context, String url, ArrayList<BasicNameValuePair> vp)
            throws IOException {
        final HttpPost post = new HttpPost(url);
        post.setEntity(new UrlEncodedFormEntity(vp, "UTF_8"));

        InputStream in = null;
        HttpEntity entity = null;
        try {
            final HttpResponse response = HttpManager.execute(context, post);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                entity = response.getEntity();
                if (entity != null) {
                    in = entity.getContent();
                    return IOUtils.stream2String(in);
                }
            } else {
                post.abort();
                mLog.error("http code: " + response.getStatusLine().getStatusCode());
            }
            return null;
        } catch (IOException ex) {
            post.abort();
            throw ex;
        } catch (RuntimeException ex) {
            post.abort();
            throw ex;
        } finally {
            if(entity!=null) {
                entity.consumeContent();
            }
            IOUtils.closeStream(in);
        }
    }

    private Object parseJson(String jsonString) throws IOException {
        try {
            JSONObject jobj = new JSONObject(jsonString);
            if (jobj.has("errorcode")) {
                return jobj.optString("errorcode");
            }

            if (jobj.has("resultlist")) {
                ArrayList<HashMap<String, String>> arrList;
                arrList = new ArrayList<HashMap<String, String>>();
                JSONArray jsonArray = jobj.optJSONArray("resultlist");
                final int len = jsonArray.length();
                for (int i = 0; i < len; i++) {
                    final JSONObject obj = (JSONObject)jsonArray.opt(i);
                    arrList.add(parse2Map(obj));
                }
                return arrList;
            } else {
                return parse2Map(jobj);
            }
        } catch (JSONException e) {
            IOException ioe = new IOException("Invalid json String...");
            ioe.initCause(e);
            throw ioe;
        }
    }

    private HashMap<String, String> parse2Map(JSONObject jsonObj) throws IOException {
        final HashMap<String, String> hashMap = new HashMap<String, String>();
        @SuppressWarnings("unchecked")
        final Iterator<String> keyIter = jsonObj.keys();
        String key, value;
        while (keyIter != null && keyIter.hasNext()) {
            key = keyIter.next();
            value = jsonObj.optString(key);
            hashMap.put(key, value);
        }
        return hashMap;
    }

    private void clearTask() {
        mTaskListener = null;
        mParameter = null;
        mContext = null;
    }

    public interface TaskListener {
        public void onSuccess(int action, Object result);
        public void onFailed(int action, String errcode, Exception ex);
    }
}


说明:

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

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

sample:

  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. }  
package xiaogang.enif.ui;

import java.util.ArrayList;

import org.apache.http.message.BasicNameValuePair;

import xiaogang.enif.R;
import xiaogang.enif.image.CacheView;
import xiaogang.enif.net.WSAPI;
import xiaogang.enif.net.WSCfg;
import xiaogang.enif.net.WSTask.TaskListener;
import xiaogang.enif.widget.ListsApdater;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity implements TaskListener {
    ListView mList;
    ListsApdater mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setupViews();
    }

    private void setupViews() {
        mList = (ListView)findViewById(R.id.list);
        mAdapter = new ListsApdater(this, mUrls);
        mList.setAdapter(mAdapter);
        final ArrayList<BasicNameValuePair> vp = new ArrayList<BasicNameValuePair>();
        vp.addAll(WSCfg.sValuePairs);
        vp.add(new BasicNameValuePair("imei", "123"));
        vp.add(new BasicNameValuePair("imsi", "123"));
        WSAPI.execute(this, this, WSCfg.USER_LOGIN, vp);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAdapter.recycle();
        CacheView.recycle();
    }

    private String[] mUrls = {
            "http://a3.twimg.com/profile_images/670625317/aam-logo-v3-twitter.png",
            "http://a3.twimg.com/profile_images/740897825/AndroidCast-350_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook.png",
            "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",
            "http://a1.twimg.com/profile_images/74724754/android_logo_normal.png",
            "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",
            "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",
            "http://a3.twimg.com/profile_images/548410609/icon_8_73.png",
            "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",
            "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",
            "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_android_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",
            "http://a1.twimg.com/profile_images/74724754/android_logo.png",
            "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",
            "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",
            "http://a3.twimg.com/profile_images/548410609/icon_8_73_normal.png",
            "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",
            "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",
            "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_android.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png"
    };

    @Override
    public void onSuccess(int action, Object result) {
        switch (action) {
            case WSCfg.USER_LOGIN:
                break;
            case WSCfg.USER_LOGOUT:
                break;
        }
    }

    @Override
    public void onFailed(int action, String errcode, Exception ex) {
        switch (action) {
            case WSCfg.USER_LOGIN:
                break;
            case WSCfg.USER_LOGOUT:
                break;
        }
    }
}
  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. }  
package xiaogang.enif.widget;

import xiaogang.enif.R;
import xiaogang.enif.image.CacheView;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ListsApdater extends BaseAdapter {
    private String[] mUrls;
    private LayoutInflater mInflater;

    public ListsApdater(Context context, String[] urls) {
        mUrls = urls;
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return mUrls.length;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (null == convertView) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.item, null);
            holder.view = (CacheView)convertView.findViewById(R.id.image);
            holder.text = (TextView)convertView.findViewById(R.id.text);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        holder.text.setText("item "+position);
        holder.view.setImageUrl(mUrls[position], R.drawable.stub);
        return convertView;
    }

    public void recycle() {
        mUrls = null;
        mInflater = null;
    }

    private class ViewHolder {
        CacheView view;
        TextView text;
    }
}


main.xml和item.xml

  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>  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />

</LinearLayout>
  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>  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <xiaogang.enif.image.CacheView
        android:id="@+id/image"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:scaleType="centerCrop"
        android:src="@drawable/stub" />

    <TextView
        android:id="@+id/text"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_gravity="left|center_vertical"
        android:layout_marginLeft="10dip"
        android:layout_weight="1"
        android:textSize="20dip" />

</LinearLayout>

例子的效果图如下:



原文地址:https://www.cnblogs.com/sode/p/2782501.html