android上的一个网络接口和图片缓存框架enif
来源:互联网 发布:疯狂追星 知乎 编辑:程序博客网 时间:2024/04/30 17:34
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;
- }
- }
- }
说明:
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>
- <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>
- <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>
说明:
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.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="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>
例子的效果图如下:
完整例子代码详见:http://code.google.com/p/enif/
或者 http://download.csdn.net/detail/androidzhaoxiaogang/4797109
- android上的一个网络接口和图片缓存框架enif
- android上的一个网络接口和图片缓存框架enif
- android上的一个网络接口和图片缓存框架enif简析
- android 上的一个网络接口和图片框架
- Android之网络图片框架UniversalImageLoader和结合LruCache缓存图片
- Picasso 强大的网络图片缓存框架
- Android性能优化之图片的本地和网络缓存
- Android:android的框架区别(网络框架、图片异步加载与缓存框架、数据框架)特点整理
- Android网络图片缓存
- Android 网络图片缓存
- Android缓存机制:LruCache+AsyncTask缓存和显示网络图片
- Android Picasso图片缓存框架的使用
- Android 主流网络图片加载缓存库框架Universal-ImageLoader的使用
- Android网络图片的三级缓存
- Android如何优雅的缓存网络图片
- 继文章‘’ 自己动手写一个轻量级的Android网络请求框架‘’后续------增加缓存功能
- 做一个简单的Android图片缓存
- android上的缓存、缓存算法和缓存框架
- DELPHI高性能大容量SOCKET并发(十):IOCP完成端口性能优化
- 如何带领好团队
- android中的OOM问题 解决原则
- 关于Hibernate的sql查询返回值的问题
- php快速排序
- android上的一个网络接口和图片缓存框架enif
- 用paint方法插入图片
- 【C++基本功补习】定时器使用及文件路径提取
- 用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeof()
- java学习笔记15--引用传递
- Oracle CRS的管理与维护
- 解决比较Oracle中CLOB字段问题--转自混世者的专栏
- 大学四年,我学到了什么(二)
- Android框架