我已经做了两年的java开发人员。
但是我从来没有在我的代码中编写过WeakReference。如何使用WeakReference使我的应用程序更高效,尤其是安卓应用程序?
发布于 2010-07-14 11:37:46
在Android中使用WeakReference与在普通的Java中使用没有什么不同。
当您需要一个对对象的引用,但又不想让该引用保护对象不被垃圾收集器攻击时,您应该考虑使用一个。一个典型的例子是,当内存使用率过高(通常使用WeakHashMap实现)时,您希望对缓存进行垃圾回收。
一定要检查一下SoftReference和PhantomReference。
编辑: Tom提出了一些关于使用WeakHashMap实现缓存的问题。这里有一篇文章列出了这些问题:WeakHashMap is not a cache!
关于WeakHashMap缓存导致Netbeans性能不佳的complaints说法,Tom是对的。
我仍然认为,使用WeakHashMap实现缓存,然后将其与使用SoftReference实现的手动缓存进行比较,这将是一次很好的学习体验。在现实世界中,你可能不会使用这些解决方案中的任何一个,因为使用像Apache JCS这样的第三方库更有意义。
发布于 2015-04-12 22:51:48
EDIT2我发现了WeakReference的另一个很好的例子。Displaying Bitmaps Efficiently培训指南中的Processing Bitmaps Off the UI Thread页显示了WeakReference在AsyncTask中的一种用法。
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}上面写着,
WeakReference to ImageView可确保AsyncTask不会阻止ImageView及其引用的任何内容被垃圾收集。不能保证在任务完成时ImageView仍然存在,所以您还必须检查onPostExecute()中的引用。例如,如果用户离开了活动,或者在任务完成之前发生了配置更改,则ImageView可能不再存在。
祝你编码愉快!
编辑我从facebook-android-sdk中找到了一个非常好的WeakReference示例。ToolTipPopup类只是一个简单的窗口小部件类,它在锚视图上方显示工具提示。我截取了一张截图。

这个类非常简单(大约200行),值得一看。在该类中,WeakReference类用于保存对锚视图引用,这非常有意义,因为即使工具提示实例的生存期比其锚视图更长,也可以对锚视图进行垃圾回收。
编码愉快!:)
让我分享一个WeakReference类的工作示例。这是一小段来自Android framework widget的代码片段,叫做AutoCompleteTextView。
简而言之,在本例中, WeakReference 类用于保存 View 对象,以防止 。
我将只复制粘贴AutoCompleteTextView的嵌套类PopupDataSetObserver类。它真的很简单,注释很好地解释了这个类。编码愉快!:)
/**
* Static inner listener that keeps a WeakReference to the actual AutoCompleteTextView.
* <p>
* This way, if adapter has a longer life span than the View, we won't leak the View, instead
* we will just leak a small Observer with 1 field.
*/
private static class PopupDataSetObserver extends DataSetObserver {
private final WeakReference<AutoCompleteTextView> mViewReference;
private PopupDataSetObserver(AutoCompleteTextView view) {
mViewReference = new WeakReference<AutoCompleteTextView>(view);
}
@Override
public void onChanged() {
final AutoCompleteTextView textView = mViewReference.get();
if (textView != null && textView.mAdapter != null) {
// If the popup is not showing already, showing it will cause
// the list of data set observers attached to the adapter to
// change. We can't do it from here, because we are in the middle
// of iterating through the list of observers.
textView.post(updateRunnable);
}
}
private final Runnable updateRunnable = new Runnable() {
@Override
public void run() {
final AutoCompleteTextView textView = mViewReference.get();
if (textView == null) {
return;
}
final ListAdapter adapter = textView.mAdapter;
if (adapter == null) {
return;
}
textView.updateDropDownForFilter(adapter.getCount());
}
};
}所述PopupDataSetObserver用于设置适配器。
public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
if (mObserver == null) {
mObserver = new PopupDataSetObserver(this);
} else if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mObserver);
}
mAdapter = adapter;
if (mAdapter != null) {
//noinspection unchecked
mFilter = ((Filterable) mAdapter).getFilter();
adapter.registerDataSetObserver(mObserver);
} else {
mFilter = null;
}
mPopup.setAdapter(mAdapter);
}最后一件事。我还想知道WeakReference在安卓应用程序中的工作示例,我可以在它的官方示例应用程序中找到一些示例。但是我真的不能理解他们中的一些用法。例如,ThreadSample和DisplayingBitmaps应用程序在其代码中使用WeakReference,但是在运行了几个测试之后,我发现get()方法从不返回null,因为被引用的视图对象在适配器中被回收,而不是垃圾回收。
发布于 2017-10-31 11:36:50
其他一些答案似乎不完整或过于冗长。这是一个通用的答案。
如何在Java和Android中使用WeakReference
您可以执行以下步骤:
WeakReference变量代码
MyClass对AnotherClass的引用很弱。
public class MyClass {
// 1. Create a WeakReference variable
private WeakReference<AnotherClass> mAnotherClassReference;
// 2. Set the weak reference (nothing special about the method name)
void setWeakReference(AnotherClass anotherClass) {
mAnotherClassReference = new WeakReference<>(anotherClass);
}
// 3. Use the weak reference
void doSomething() {
AnotherClass anotherClass = mAnotherClassReference.get();
if (anotherClass == null) return;
// do something with anotherClass
}
}AnotherClass对MyClass有很强的引用。
public class AnotherClass {
// strong reference
MyClass mMyClass;
// allow MyClass to get a weak reference to this class
void someMethod() {
mMyClass = new MyClass();
mMyClass.setWeakReference(this);
}
}备注
MyClass是A,AnotherClass是B。WeakReference的替代方法是让另一个类实现一个接口。这是在Listener/Observer Pattern.中完成的
实际例子
https://stackoverflow.com/questions/3243215
复制相似问题