Android 软引用和弱引用详解及实例代码
Android软引用和弱引用
1. SoftReference<T>:软引用-->当虚拟机内存不足时,将会回收它指向的对象;需要获取对象时,可以调用get方法。
2. WeakReference<T>:弱引用-->随时可能会被垃圾回收器回收,不一定要等到虚拟机内存不足时才强制回收。要获取对象时,同样可以调用get方法。
3.WeakReference一般用来防止内存泄漏,要保证内存被虚拟机回收,SoftReference多用作来实现缓存机制(cache);
实例 SoftReference
如果一个对象只具有软引用,那就类似于可有可无的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
比如在图片加载框架中,通过弱引用来实现内存缓存。
packagecom.stevenhu.lit; importjava.lang.ref.SoftReference; importjava.net.URL; importjava.util.HashMap; importjava.util.Map; importandroid.graphics.drawable.Drawable; importandroid.os.Handler; importandroid.os.Message; //实现图片异步加载的类 publicclassAsyncImageLoader { //以Url为键,SoftReference为值,建立缓存HashMap键值对。 privateMap<String,SoftReference<Drawable>>mImageCache= newHashMap<String,SoftReference<Drawable>>(); //实现图片异步加载 publicDrawableloadDrawable(finalStringimageUrl,finalImageCallbackcallback) { //查询缓存,查看当前需要下载的图片是否在缓存中 if(mImageCache.containsKey(imageUrl)) { SoftReference<Drawable>softReference=mImageCache.get(imageUrl); if(softReference.get()!=null) { returnsoftReference.get(); } } finalHandlerhandler=newHandler() { @Override publicvoiddispatchMessage(Messagemsg) { //回调ImageCallbackImpl中的imageLoad方法,在主线(UI线程)中执行。 callback.imageLoad((Drawable)msg.obj); } }; /*若缓存中没有,新开辟一个线程,用于进行从网络上下载图片, *然后将获取到的Drawable发送到Handler中处理,通过回调实现在UI线程中显示获取的图片 */ newThread() { publicvoidrun() { Drawabledrawable=loadImageFromUrl(imageUrl); //将得到的图片存放到缓存中 mImageCache.put(imageUrl,newSoftReference<Drawable>(drawable)); Messagemessage=handler.obtainMessage(0,drawable); handler.sendMessage(message); }; }.start(); //若缓存中不存在,将从网上下载显示完成后,此处返回null; returnnull; } //定义一个回调接口 publicinterfaceImageCallback { voidimageLoad(Drawabledrawable); } //通过Url从网上获取图片Drawable对象; protectedDrawableloadImageFromUrl(StringimageUrl) { try{ returnDrawable.createFromStream(newURL(imageUrl).openStream(),"debug"); }catch(Exceptione){ //TODO:handleexception thrownewRuntimeException(e); } } }
弱引用(WeakReference)
只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
WeakReference<User>sr=newWeakReference<User>(newUser());
Handler弱引用,防止内存泄漏
packagerxnet.zyj.com.myapplication; importandroid.os.Bundle; importandroid.os.Handler; importandroid.os.Message; importandroid.support.v7.app.AppCompatActivity; importjava.lang.ref.WeakReference; publicclassMainActivityextendsAppCompatActivity{ privateHandlerhandler; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler=newMyHandler(this); newThread(newRunnable(){ @Override publicvoidrun(){ handler.sendEmptyMessage(0); } }).start(); } privatestaticclassMyHandlerextendsHandler{ WeakReference<MainActivity>weakReference; publicMyHandler(MainActivityactivity){ weakReference=newWeakReference<MainActivity>(activity); } @Override publicvoidhandleMessage(Messagemsg){ super.handleMessage(msg); if(weakReference.get()!=null){ //updateandroidui } } } }