【问题标题】:Volley throws exception onBackPressed?Volley 在BackPressed 上抛出异常?
【发布时间】:2015-03-03 18:15:31
【问题描述】:

我正在使用 Volley API 来使用 Web 服务。它工作正常,但是当我按下设备背面的按钮时,会引发异常NullPointerException 并停止应用程序。我认为这个问题是因为有一个待处理的请求,但我无法解决它。我尝试在onBackPressed 中使用cancelPendingRequests,但仍然不起作用。

我该如何解决?

凌空单例

public class CustomVolleySingleton extends Application{

    private static CustomVolleySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;

    public static final String TAG = "VolleyPatterns";

    private CustomVolleySingleton(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 CustomVolleySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new CustomVolleySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {            
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setRetryPolicy(new DefaultRetryPolicy(
                           120000,
                           DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                           DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

onBackPressed

@Override
    public void onBackPressed() {
           CustomVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests(CustomVolleySingleton.TAG);
            super.onBackPressed();

    }

例外

03-03 15:28:48.689  24175-24175/br.com.myapp.batalhajuridica E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: br.com.myapp.batalhajuridica, PID: 24175
    java.lang.NullPointerException
            at br.com.myapp.batalhajuridica.frags.JogosAbertosFrag$1.getListBatalhaAbertaFechada(JogosAbertosFrag.java:121)
            at br.com.myapp.batalhajuridica.dao.BatalhaDAO$5.onResponse(BatalhaDAO.java:206)
            at br.com.myapp.batalhajuridica.dao.BatalhaDAO$5.onResponse(BatalhaDAO.java:136)
            at br.com.myapp.batalhajuridica.cv.ApplicationController.deliverResponse(ApplicationController.java:81)
            at br.com.myapp.batalhajuridica.cv.ApplicationController.deliverResponse(ApplicationController.java:28)
            at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5356)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
            at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 显示您的日志以查看错误,这将有很大帮助...
  • Android 将为您创建一个CustomVolleySingleton 应用程序对象,而您正在创建另一个。而是尝试将getApplicationContext() 转换为CustomVolleySingleton 而不是调用getInstance()
  • @RichardLeMesurier 抱歉,我听不懂你说什么。
  • 基本上我的意思是......像 Shifar 为他的单身人士所做的那样。你的单身人士是错误的。 stackoverflow.com/a/28839145/383414
  • 是的,没错,arnab.ch 的做法与 Shifar 的做法相同。您正在以不同的方式初始化您的实例,采用标准 Java 方式,不适用于 Android Application 对象。请注意您如何在新对象上使用延迟初始化。其他代码不会延迟初始化,因为Application 已经是一个单例,并且在任何 Android 代码运行时始终初始化。祝你好运

标签: android android-volley


【解决方案1】:

这是一个很好的 SingletonClass 来玩 volley

import android.app.Application;
import android.text.TextUtils;
import android.util.Log;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class AppController extends Application {

    public static final String TAG = AppController.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static AppController mAppController;

    @Override
    public void onCreate() {
        super.onCreate();
        mAppController =  this;
    }

    //Getting App Controller Instance
    public static synchronized AppController getInstance()
    {
        Log.d("X","AppController Instance Passed");
        return mAppController;
    }

    //Getting Request Queue
    public RequestQueue getRequestQueue()
    {
        Log.d("X","Request que passed");
        if(mRequestQueue==null)
        {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    //Getting image Loader
    public ImageLoader getImageLoader()
    {
        Log.d("X","ImageLoader passed");
        getRequestQueue();
        if(mImageLoader==null)
        {
            mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
        }
        return this.mImageLoader;
    }

    //Adding to requestque with tag
    public <T> void addToRequestQueue(Request<T> req,String tag)
    {   
        Log.i("X","Added to Request Que");
        req.setTag(TextUtils.isEmpty(tag)? TAG : tag);
        getRequestQueue().add(req);
    }

    //Adding to Request que without custom tag
    public <T> void addToRequestQueue(Request<T> req)
    {
        Log.i("X","Added to Request Que");
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(String tag)
    {
        if(mRequestQueue!=null)
        {
            mRequestQueue.cancelAll(tag);
        }
    }


}

LruBitmapCache.java

public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageCache {

    //Getting cache size    
    public static int getDefaultLruCacheSize() {
        Log.d("X","Cache size provided");
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    //No parm Constructor
    public LruBitmapCache()
    {
        //Calling second constructor
        this(getDefaultLruCacheSize());
    }

    //Second Constructor
    public LruBitmapCache(int maxSize) {
        super(maxSize);
    }


    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }


}

并像这样使用

//Volley JSONArrayRequest
        JsonArrayRequest mJsonArrayRequest = new JsonArrayRequest(URL, new Response.Listener<JSONArray>() {

            @Override
            public void onResponse(JSONArray response) {

                //Play with the JSONArray response here

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError err) {
                //Handle the error here
            }

        });

        //Adding to Queue
        AppController.getInstance().addToRequestQueue(mJsonArrayRequest);

【讨论】:

    【解决方案2】:
    import android.app.Application;
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.android.volley.Request;
    import com.android.volley.RequestQueue;
    import com.android.volley.toolbox.ImageLoader;
    import com.android.volley.toolbox.Volley;
    
    public class AppController extends Application {
    public static final String TAG = AppController.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static AppController mAppController;
    
    @Override
    public void onCreate() {
        super.onCreate();
        mAppController =  this;
    }
    
    //Getting App Controller Instance
    public static synchronized AppController getInstance()
    {
        Log.d("X","AppController Instance Passed");
        return mAppController;
    }
    
    //Getting Request Queue
    public RequestQueue getRequestQueue()
    {
        Log.d("X","Request que passed");
        if(mRequestQueue==null)
        {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
    
        return mRequestQueue;
    }
    
    //Getting image Loader
    public ImageLoader getImageLoader()
    {
        Log.d("X","ImageLoader passed");
        getRequestQueue();
        if(mImageLoader==null)
        {
            mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
        }
        return this.mImageLoader;
    }
    
    //Adding to requestque with tag
    public <T> void addToRequestQueue(Request<T> req,String tag)
    {   
        Log.i("X","Added to Request Que");
        req.setTag(TextUtils.isEmpty(tag)? TAG : tag);
        getRequestQueue().add(req);
    }
    
    //Adding to Request que without custom tag
    public <T> void addToRequestQueue(Request<T> req)
    {
        Log.i("X","Added to Request Que");
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
    
    public void cancelPendingRequests(String tag)
    {
        if(mRequestQueue!=null)
        {
            mRequestQueue.cancelAll(tag);
        }
    }
    

    } 和 LruBitmapCache.java

    公共类 LruBitmapCache 扩展 LruCache 实现 ImageCache {

    //Getting cache size    
    public static int getDefaultLruCacheSize() {
        Log.d("X","Cache size provided");
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
    
        return cacheSize;
    }
    
    //No parm Constructor
    public LruBitmapCache()
    {
        //Calling second constructor
        this(getDefaultLruCacheSize());
    }
    
    //Second Constructor
    public LruBitmapCache(int maxSize) {
        super(maxSize);
    }
    
    
    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }
    
    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }
    
    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
    

    } 并像这样使用

    //Volley JSONArrayRequest JsonArrayRequest mJsonArrayRequest = new JsonArrayRequest(URL, new Response.Listener() {

            @Override
            public void onResponse(JSONArray response) {
    
                //Play with the JSONArray response here
    
            }
        }, new Response.ErrorListener() {
    
            @Override
            public void onErrorResponse(VolleyError err) {
                //Handle the error here
            }
    
        });
    
        //Adding to Queue
        AppController.getInstance().addToRequestQueue(mJsonArrayRequest);
    

    【讨论】:

      【解决方案3】:

      看看这个

      import android.app.Application;
      import android.text.TextUtils;
      import android.util.Log;
      
      import com.android.volley.Request;
      import com.android.volley.RequestQueue;
      import com.android.volley.toolbox.ImageLoader;
      import com.android.volley.toolbox.Volley;
      
      public class AppController extends Application {
      
          public static final String TAG = AppController.class.getSimpleName();
          private RequestQueue mRequestQueue;
          private ImageLoader mImageLoader;
          private static AppController mAppController;
      
          @Override
          public void onCreate() {
              super.onCreate();
              mAppController =  this;
          }
      
          //Getting App Controller Instance
          public static synchronized AppController getInstance()
          {
              Log.d("X","AppController Instance Passed");
              return mAppController;
          }
      
          //Getting Request Queue
          public RequestQueue getRequestQueue()
          {
              Log.d("X","Request que passed");
              if(mRequestQueue==null)
              {
                  mRequestQueue = Volley.newRequestQueue(getApplicationContext());
              }
      
              return mRequestQueue;
          }
      
          //Getting image Loader
          public ImageLoader getImageLoader()
          {
              Log.d("X","ImageLoader passed");
              getRequestQueue();
              if(mImageLoader==null)
              {
                  mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
              }
              return this.mImageLoader;
          }
      
          //Adding to requestque with tag
          public <T> void addToRequestQueue(Request<T> req,String tag)
          {   
              Log.i("X","Added to Request Que");
              req.setTag(TextUtils.isEmpty(tag)? TAG : tag);
              getRequestQueue().add(req);
          }
      
          //Adding to Request que without custom tag
          public <T> void addToRequestQueue(Request<T> req)
          {
              Log.i("X","Added to Request Que");
              req.setTag(TAG);
              getRequestQueue().add(req);
          }
      
          public void cancelPendingRequests(String tag)
          {
              if(mRequestQueue!=null)
              {
                  mRequestQueue.cancelAll(tag);
              }
          }
      
      
      }
      

      【讨论】:

        【解决方案4】:

        这样做

        import android.app.Application;
        import android.text.TextUtils;
        import android.util.Log;
        
        import com.android.volley.Request;
        import com.android.volley.RequestQueue;
        import com.android.volley.toolbox.ImageLoader;
        import com.android.volley.toolbox.Volley;
        
        public class AppController extends Application {
        
            public static final String TAG = AppController.class.getSimpleName();
            private RequestQueue mRequestQueue;
            private ImageLoader mImageLoader;
            private static AppController mAppController;
        
            @Override
            public void onCreate() {
                super.onCreate();
                mAppController =  this;
            }
        
            //Getting App Controller Instance
            public static synchronized AppController getInstance()
            {
                Log.d("X","AppController Instance Passed");
                return mAppController;
            }
        
            //Getting Request Queue
            public RequestQueue getRequestQueue()
            {
                Log.d("X","Request que passed");
                if(mRequestQueue==null)
                {
                    mRequestQueue = Volley.newRequestQueue(getApplicationContext());
                }
        
                return mRequestQueue;
            }
        
            //Getting image Loader
            public ImageLoader getImageLoader()
            {
                Log.d("X","ImageLoader passed");
                getRequestQueue();
                if(mImageLoader==null)
                {
                    mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
                }
                return this.mImageLoader;
            }
        
            //Adding to requestque with tag
            public <T> void addToRequestQueue(Request<T> req,String tag)
            {   
                Log.i("X","Added to Request Que");
                req.setTag(TextUtils.isEmpty(tag)? TAG : tag);
                getRequestQueue().add(req);
            }
        
            //Adding to Request que without custom tag
            public <T> void addToRequestQueue(Request<T> req)
            {
                Log.i("X","Added to Request Que");
                req.setTag(TAG);
                getRequestQueue().add(req);
            }
        
            public void cancelPendingRequests(String tag)
            {
                if(mRequestQueue!=null)
                {
                    mRequestQueue.cancelAll(tag);
                }
            }
        
        
        }
        

        【讨论】:

          猜你喜欢
          • 2017-06-13
          • 2013-05-24
          • 2011-05-25
          • 2015-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多