getInstance(this)添加ImageLoader时出现Android Volley错误

我正在使用Volley在Android开发人员跟踪图像兑现教程 ,我有问题请求图像请求并caching它,我猜是因为我创build的singelton(从教程复制)。

我的Eclipse在getInstance(this)给出错误,因为这是上下文,我正在请求一个图像,我猜。

 ImageRequest request = new ImageRequest( url, new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { mNetworkImageView = (NetworkImageView) findViewById(R.id.ImageView); mImageLoader = MySingleton.getInstance(this).getImageLoader(); mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader); // mImageLoader = MySingleton.getInstance(this).getImageLoader(); // mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView, // R.drawable.ic_launcher, R.drawable.ic_launcher)); } }, 0, 0, null, new Response.ErrorListener() { public void onErrorResponse(VolleyError error) { // mImageView.setImageResource(R.drawable.ic_launcher); } }); MySingleton.getInstance(this).addToRequestQueue(request); 

这是单身人士:

 package com.example.p; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.Volley; import android.content.Context; import android.graphics.Bitmap; import android.support.v4.util.LruCache; 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; } } 

我能够以这种方式获取图像并显示它,但是我需要caching它,所以我想它会将它添加到请求中吗? ..任何帮助?

 mNetworkImageView = (NetworkImageView) findViewById(R.id.ImageView); mImageLoader = MySingleton.getInstance(this).getImageLoader(); mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader); 

Solutions Collecting From Web of "getInstance(this)添加ImageLoader时出现Android Volley错误"

这是我的工作示例代码。 希望这个帮助:

MainActivity.java:

 import ... public class MainActivity extends Activity { final Context mContext = this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NetworkImageView mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView); String mUrl = "http://192.168.0.100/api/getimage"; mNetworkImageView.setImageUrl(mUrl, VolleySingleton.getInstance(mContext).getImageLoader()); } ... } 

VolleySingleton.java:

 public class VolleySingleton { private static VolleySingleton mInstance; private RequestQueue mRequestQueue; private ImageLoader mImageLoader; private static Context mContext; private VolleySingleton(Context context) { mContext = context; mRequestQueue = getRequestQueue(); mImageLoader = new ImageLoader(mRequestQueue, 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 VolleySingleton getInstance(Context context) { if (mInstance == null) { mInstance = new VolleySingleton(context); } return mInstance; } private 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(mContext.getApplicationContext(), 10 * 1024 * 1024); // this for caching } return mRequestQueue; } public <T> void addToRequestQueue(Request<T> req) { getRequestQueue().add(req); } public ImageLoader getImageLoader() { return mImageLoader; } } 

activity_main.xml中:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" tools:context=".MainActivity"> <com.android.volley.toolbox.NetworkImageView android:id="@+id/networkImageView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 

AndroidManifest.xml中:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.volleyapp" > <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

你在错误的上下文中。初始化一个类成员

 private final Context ctx = this; 

而不是在onResponse里面使用ctx

 mImageLoader = MySingleton.getInstance(ctx).getImageLoader(); 

getInstance方法的一个优化build议是使用双重检查locking,因为它仅在实例实际为空时进行同步:

 private volatile static VolleySingleton self; public static VolleySingleton getInstance(Context context) { if (self == null) { //Using double checked locking synchronized (VolleySingleton.class) { if (self == null) { //Using app context prevents leaking of activity context self = new VolleySingleton(context.getApplicationContext()); } } } return self; } 

有关单例的更多信息和实例化它们的不同方法可以在这里find。

volatile关键字确保该字段立即被所有线程看到并且不被线程caching到本地。 如果getInstance不需要Context,还有其他的方法在链接中解释,比双重检查locking更合适。