web-dev-qa-db-fra.com

Échec du lancement de OutOfMemoryError "pthread_create (pile de 1040 Ko): réessayez" lors de la publication de messages asynchrones à l'aide de Volley

J'utilise Volley pour POST certaines données stockées dans une base de données locale sur un serveur. Le problème est quand j'ai un grand nombre d'entrées (par exemple 500) j'obtiens cette erreur:

 Java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
at Java.lang.Thread.nativeCreate(Native Method)
at com.Android.volley.RequestQueue.start(RequestQueue.Java:141)
at com.Android.volley.toolbox.Volley.newRequestQueue(Volley.Java:66)
at com.Android.volley.toolbox.Volley.newRequestQueue(Volley.Java:66)
at mypackageName.SomeClass.upload(SomeClass)
at mypackageName.MyClass$MyThred.run(SomeClass.Java:387)

Voici comment je récupère les données du curseur et fais le post

    private class UploadDataThred extends Thread {

    @Override
    public void run() {
        SomeSQLiteHelper someSQLiteHelper = new SomeSQLiteHelper(context);
        someSQLiteHelper.getWritableDatabase();
        Cursor result = someSQLiteHelper.getAllEvents();
        DataUploader dataUploader = new DataUploader(context);

        while (result.moveToNext()) {
            Build.logError("We're looping!");
            while (!waitingForResponse) {
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            dataUploader.upload(result.getString(0), false, result.getString(1), result.getString(2), result.getString(3), result.getString(4), result.getString(5), result.getString(6), result.getString(7), result.getString(8));

        }
        someSQLiteHelper.close();
    }
}

et c'est ma méthode qui fait le POST

 public void upload(Some parameters go here) {

    waitingForResponse = true;
    VolleyLog.DEBUG = false;


    final JSONObject o = new JSONObject();
    o.put(Some data)

    RequestQueue requestQueue = Volley.newRequestQueue(context);

    JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST, Host,  o, new Response.Listener<JSONObject>() {


        @Override
        public void onResponse(JSONObject response) {

            if (response.toString().contains("OK")) {

                if (columnID != null) {

                deleteSingleEntry(columnID);

                }


                waitingForResponse = false;


            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

            waitingForResponse = false;

        }
    }) {

        /**
         * Passing some request headers
         * */
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Content-Type", "application/json; charset=utf-8");
            return headers;
        }


    };



    requestQueue.add(jsonObjReq);

}

Cela fonctionne très bien si j'ai 400 entrées dans la base de données locale et après cela, il lance cette exécution. Merci d'avance.

21
android enthusiast

Le problème est que je créais une nouvelle RequestQueue pour chaque demande. C'est la raison pour laquelle je soupçonne qu'il lève l'exception OutOfMemory. La solution est simple:

au lieu de RequestQueue requestQueue = Volley.newRequestQueue(context);

déclarer la RequestQueue en dehors de la méthode et ajouter une nouvelle RequestQueue uniquement si la précédente est nulle.

private RequestQueue requestQueue;

public void uploadData(String s) {
if (requestQueue == null) {
        requestQueue = Volley.newRequestQueue(context);
        Build.logError("Setting a new request queue");
    } more request stuff....
}
43

En remarque, j'ai eu la même erreur de socket.io, chaque fois que je me reconnectais avec socket.connect (), un nouveau thread commençait avec l'ancien thread toujours en cours d'exécution.

Résolu en appelant socket.disconnect () avant socket.connect (). Même si socket est déjà déconnecté, appeler socket.disconnect () détruira l'ancien thread pour vous

Ce n'est pas réellement lié à la question elle-même, mais j'ai eu la même erreur "outofmemoryerror pthread_create", qui n'est pas causée par Volley mais par socket.io créant de nouveaux threads chaque fois que l'utilisateur essaie de se reconnecter manuellement (en appelant socket.connect, au lieu de définir l'option "reconnecter" sur true). Quand je cherchais la solution, je suis venu à cette question et après avoir résolu le problème, j'ai décidé d'ajouter la solution ici, juste au cas où quelqu'un d'autre aurait le même problème

7
Alatoo