类似的问题一直是asked here,here和here,但背景与此完全不同,此外code that gave from this error由Android和Android Studio制作人撰写
这是代码:
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private MySingleton(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 MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(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) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
发出警告的行是:
private static MySingleton mInstance;
private static Context mCtx;
现在,如果我删除了static
关键字,请将public static synchronized MySingleton getInstance(Context...
更改为public synchronized MySingleton getInstance(Context...
错误消息,但会出现另一个问题。
我在RecyclerView中使用MySingleton
。所以这一行
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
ImageLoader imageLoader = MySingleton.getInstance(mContext).getImageLoader();
告诉我
非静态方法'getInstance(android.content.Context)'无法从静态上下文中获取。
请有人知道如何解决这个问题吗?
答案 0 :(得分:15)
我在answer to a similar question answered by CommonsWare
中找到了解决方法我引用
引用的Lint警告并没有抱怨创建单身人士。 它抱怨创建单身人士持有一个参考 任意上下文,因为它可能类似于Activity。 希望通过将mContext = context更改为mContext = context.getApplicationContext(),你将摆脱那个警告 (虽然有可能这仍然打破了瞬间跑 - 我不能 真的评论那个。)
创建单身人士是好的,只要你非常小心地这样做 避免内存泄漏(例如,保持一个不确定的静态引用 活性)。
因此谷歌实际上并没有签约。要解决这个问题,如果提供this.getApplicationContext
作为上下文的参数,那么就不会有内存泄漏。
因此,实质上,忽略警告并提供this.getApplicationContext
作为上下文的参数。
答案 1 :(得分:4)
我最终把它放在没有警告的AppController中。
public class AppController extends MultiDexApplication {
public static Context getContext() {
return mInstance.getApplicationContext();
}
private static AppController mInstance;
public static synchronized AppController getInstance() {
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
}
因此,无论何时需要,只需致电AppController.getContext()
答案 2 :(得分:0)
我只是删除了对上下文的静态引用,并且没有错误:
public class RequestQueueSingleton {
private RequestQueue requestQueue;
private final ImageLoader imageLoader;
private final Context ctx;
private RequestQueueSingleton(Context context) {
ctx = context;
requestQueue = getRequestQueue();
imageLoader = new ImageLoader(requestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<>(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 RequestQueueSingleton getInstance(Context context) {
RequestQueueSingleton instance;
instance = new RequestQueueSingleton(context);
return instance;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
return requestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
答案 3 :(得分:-1)
这是我的解决方案。当您刚刚返回RequestQueue的实例时,无需保留静态引用?
public class VolleyRequestQueue {
private static VolleyRequestQueue mInstance;
private RequestQueue mRequestQueue;
private VolleyRequestQueue() {
}
public static synchronized VolleyRequestQueue getInstance() {
if(mInstance == null) {
mInstance = new VolleyRequestQueue();
}
return mInstance;
}
public RequestQueue getRequestQueue(Context context) {
if(mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(context.getApplicationContext());
}
return mRequestQueue;
}
}
答案 4 :(得分:-1)
我写了这个单例类,没有发现内存泄漏或其他警告。
using (var connection = new SqlConnection(connectionString))
using (var command = connection.CreateCommand())
{
command.CommandText = "UPDATE Student SET Name = @name where id = @id";
command.Parameters.AddWithValue("@name", name);
command.Parameters.AddWithValue("@id", myId);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}