广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

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

    2018-04-03 22:30:47 次阅读 稿源:互联网
    广告
    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>

    例子的效果图如下

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告