我有一个应用程序,我需要在运行时获取imageView的高度和宽度。我已经找到了一个使用post方法的解决方案,该方法在绘制View之后被调用。我目前在应用程序中存在内存泄漏的巨大问题。我最近几天一直在使用Android Monitor,MAT和泄漏金丝雀。我已经删除了引起泄漏的所有内容,但实际问题无法跟踪。我怀疑post方法实际上可能持有对activity / fragment的引用。我不确定。以下代码片段是否会导致内存泄漏,或者我是否在寻找错误的位置。
imageView.post(new Runnable() {
@Override
public void run() {
Picasso.with(getActivity().getApplicationContext())
.load(R.drawable.download)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.resize(imageView.getWidth() / 3, imageView.getHeight() / 3)
.noFade()
.error(R.drawable.gradient_background_shop)
.into(imageView);
}
});
另外,我正在使用Volley库进行数据获取。但我注意到Leak Canary暗示网络调度程序正在泄漏内存。我在我的Application类中使用单例模式,其中volley被初始化。 Volley真的会引起问题吗?
public class YouStyleMe extends Application {
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static YouStyleMe mInstance;
public static Context mCtx;
public static final String TAG = YouStyleMe.class
.getSimpleName();
public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
public YouStyleMe() {
}
private YouStyleMe(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
public static synchronized YouStyleMe getInstance(Context context) {
if (mInstance == null) {
mInstance = new YouStyleMe(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public void cancelPendingRequests() {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(TAG);
}
}
}
答案 0 :(得分:0)
使用处理程序
像这样初始化它:
private Handler mHandler = new Handler();
然后,不要发布匿名的runnable,声明如下:
updateCall = new WeakReference<Runnable>(new Runnable() {
@Override
public void run() {
...
}
});
并使用处理程序或ImageView
imageView.post(updateCall.get());
那些应该有所帮助。
另一个大问题是这一行:
private static YouStyleMe mInstance;
由于private static
属性,该对象将具有非常长的寿命,并且大多数子对象(成员)将永远可以访问。这意味着GC不会获取它们,因为它只清除不再可访问的对象。甚至不强制GC会清理它们。
因此,请尝试解决此问题,或将您的mInstance设为WeakReference
。