1: The network's underlying environment uses Apache's httpclient link pool framework
2: Image cache with LRU based algorithm
3: Network interface with listener mode
4 oom processing with pictures (application of timely recovery processing technology)
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 would 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 <<) >> 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;
}
}
}
Description
1) entryremoved in bitmap recyle when the three conditions are indispensable
2) OnDraw inside to determine whether the picture is recycled, if the collection needs to set the default picture
3) Add bitmap to Cache Runtime.getruntime (). Call of the GC
Reprint http://blog.csdn.net/androidzhaoxiaogang/article/details/8211649
A network interface and picture frame on Android