引用:http://blog.csdn.net/androidzhaoxiaogang/article/details/8211649
1.底层网络接口采用apache的httpclient连接池框架;
2.图片缓存采用基于LRU的算法;
3.网络接口采用监听者模式;
4.包含图片的OOM处理(及时回收处理技术的应用);
图片核心处理类:CacheView.java
- 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;
- }
- }
- }
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
- <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"));
- }
- }</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")); } }
- <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.
- }
- }
- }
- </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. } } }
- <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);
- }
- }
- </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:
- 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;
- }
- }
- }
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; } } }
- 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;
- }
- }
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
- <?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>
<?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>
- <?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>
<?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>
例子的效果图如下: