How to use WeakReference in Java and Android development?
我做Java开发已经有2年了。
但我从未在我的代码中写过一个weakreference。如何使用weakreference使我的应用程序更高效,尤其是Android应用程序?
在Android中使用EDCOX1的0度与使用普通的Java没有什么不同。下面是一个很好的指南,它给出了一个详细的解释:理解薄弱的参考。
当需要对象引用时,应该考虑使用一个,但您不希望该引用保护对象不受垃圾收集器的影响。一个典型的例子是当内存使用率过高时(通常使用
一定要查看
编辑:Tom对使用
Tom说得对,有人抱怨NetBeans由于
我仍然认为使用
[edit2]我发现了另一个很好的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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); } } } } |
它说,
The WeakReference to the ImageView ensures that the AsyncTask does not prevent the ImageView and anything it references from being garbage collected. There’s no guarantee the ImageView is still around when the task finishes, so you must also check the reference in onPostExecute(). The ImageView may no longer exist, if for example, the user navigates away from the activity or if a configuration change happens before the task finishes.
快乐编码!
[编辑]我从facebook android sdk找到了一个很好的
这门课很简单(大约200行),值得一看。在该类中,
快乐编码!:)
让我分享一个
简而言之,在本例中,
我只复制并粘贴PopupDatasetObserver类,它是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /** * 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()); } }; } |
设置适配器时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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); } |
最后一件事。我还想知道android应用程序中
其他一些答案似乎不完整或太长。这是一个一般的答案。
如何在Java和Android中使用弱引用您可以执行以下步骤:
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class MyClass { // 1. Create a WeakReference variable private WeakReference<AnotherClass> mAnotherClassReference; // 2. Set the weak reference void someMethod(AnotherClass object) { mAnotherClassReference = new WeakReference<>(object); } // 3. Use the weak reference void anotherMethod() { AnotherClass object = mAnotherClassReference.get(); if (object == null) return; // do something with the object } } |
1 2 3 4 5 6 7 8 9 10 11 | public class AnotherClass { // strong reference MyClass mMyClass; // allow MyClass to get a weak reference to this class void someMethod() { mMyClass = new MyClass(); mMyClass.someMethod(this); } } |
笔记
- 需要弱引用的原因是垃圾收集器可以在不再需要对象时对其进行处理。如果两个对象保留了彼此的强引用,那么它们就不能被垃圾收集。这是内存泄漏。
- 如果两个物体需要相互参照,A物体(一般是较短寿命的物体)应该对B物体(一般是较长寿命的物体)有弱参照,B物体对A有强参照,在上例中,
MyClass 是A,AnotherClass 是B。 - 使用
WeakReference 的一个替代方法是让另一个类实现一个接口。这是在侦听器/观察器模式中完成的。
实例
- 静态内部异步任务类
"规范化"映射是指将对象的一个实例保存在内存中,而所有其他实例都通过指针或其他类似机制查找该特定实例。这就是weaks的参考可以帮助的地方。简而言之,weakreference对象可用于创建指向系统中对象的指针,同时还允许垃圾收集器在这些对象超出范围后回收这些对象。例如,如果我有这样的代码:
1 2 3 4 5 6 7 |
GC永远不会回收我注册的任何对象,因为它有一个引用存储在
1 2 3 4 5 6 7 | class Registry { private Set registeredObjects = new HashSet(); public void register(Object object) { registeredObjects.add( new WeakReference(object) ); } } |
然后当GC想要回收集合中的对象时,它将能够这样做。您可以将此技术用于缓存、编目等。有关GC和缓存的更深入讨论的参考,请参见下文。
参考:垃圾收集器和Weakreference