使用Volley在后台服务上出现OutofMemory错误

时间:2015-09-04 19:15:46

标签: java android service android-volley

我正在制作一个始终运行后台服务的应用程序。但问题是,在几个小时之后,它会引发以下内存不足错误:

09-04 22:08:09.110  13810-13810/? I/art? Late-enabling -Xcheck:jni
09-04 22:08:09.165  13810-13810/com.mts.myapp I/MyService? FileScannerService Timer started....
09-04 22:08:10.265  13810-13834/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:10.280  13810-13834/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2648453 free bytes and 88MB until OOM"
09-04 22:08:10.310  13810-13834/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:10.350  13810-13834/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2648538 free bytes and 88MB until OOM"
09-04 22:08:10.355  13810-13834/com.mts.myapp E/AndroidRuntime? FATAL EXCEPTION: Thread-1654
    Process: com.mts.myapp, PID: 13810
    java.lang.OutOfMemoryError: Failed to allocate a 1627389964 byte allocation with 2648538 free bytes and 88MB until OOM
            at com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:316)
            at com.android.volley.toolbox.DiskBasedCache.readString(DiskBasedCache.java:526)
            at com.android.volley.toolbox.DiskBasedCache.readStringStringMap(DiskBasedCache.java:549)
            at com.android.volley.toolbox.DiskBasedCache$CacheHeader.readHeader(DiskBasedCache.java:392)
            at com.android.volley.toolbox.DiskBasedCache.initialize(DiskBasedCache.java:155)
            at com.android.volley.CacheDispatcher.run(CacheDispatcher.java:84)
09-04 22:08:25.260  13810-13949/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:25.280  13810-13949/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2651578 free bytes and 88MB until OOM"
09-04 22:08:25.310  13810-13949/com.mts.myapp I/art? Forcing collection of SoftReferences for 1GB allocation
09-04 22:08:25.330  13810-13949/com.mts.myapp E/art? Throwing OutOfMemoryError "Failed to allocate a 1627389964 byte allocation with 2651568 free bytes and 88MB until OOM"
09-04 22:08:25.330  13810-13949/com.mts.myapp I/Process? Sending signal. PID: 13810 SIG: 9

serice在定义的时间间隔内使用截击进行Http调用。检查返回的JSONObject并在必要时显示通知。

那么您认为导致内存不足的错误是什么?

这是截击:

RequestQueue queue = Volley.newRequestQueue(this);
        String url = "http://myrequesturl.com"
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        //DO STUFF


                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        });
        queue.add(stringRequest);

2 个答案:

答案 0 :(得分:3)

每次使用http请求最佳方法是使用请求队列的单个对象并为每个请求重复使用时,您的服务都会创建新的请求队列。

这是代码示例 //创建新的Java文件App.java

public class App extends Application {
    public static final String TAG = App.class.getSimpleName();
    private static App mInstance;

    private RequestQueue mRequestQueue;

    public static synchronized App getInstance() {
        return mInstance;
    }

    @Override
    public void onCreate() {

        super.onCreate();

        mRequestQueue = Volley.newRequestQueue(getApplicationContext());

        mInstance = this;

    }

    public RequestQueue getRequestQueue() {
        return mRequestQueue;
    }


    public <T> void addToRequestQueue(Request<T> request, String tag) {
        request.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(request);
    }

    public <T> void addToRequestQueue(Request<T> request) {
        request.setTag(TAG);
        getRequestQueue().add(request);
    }

    public void cancelPendingRequest(Object tag) {
        getRequestQueue().cancelAll(tag);
    }

}

//在该应用程序类的android清单引用名称中

 <application
        android:name=".App"
        ....

//现在,当您提出请求时

App.getInstance().addToRequestQueue(stringRequest);

这将只创建一个请求队列实例,并将其用于每个请求

答案 1 :(得分:0)

某处存在内存泄漏。

此代码似乎创建了一个新的RequestQueue,每次调用都不是推荐的方法。

您应该创建一个RequestQueue,然后将我们的请求添加到此单个队列。