Various ProgressDialog in recursive request using Volley and AsyncTask

3

Hi, I'm doing request using the library Volley to API to get many records approximately 8,000 and save them in BD .

The response of API brings a parameter count with the total of the objects and the parameter next with the next url, for each request returns 500 objetos .

During the JsonObjectRequest I use a ProgressDialog with style Spinner , if the request brings objects in the onResponse of JsonObjectRequest I made the parse of the response in a AsyncTask .

When I run the AsyncTask to perform the parser and save the information in BD I use a horizontal style ProgressDialog indicating the percentage of the task.

The problem is the ProgressDialog during the request to the API this is executed only the first time and from the second I get the following error:

01-28 18:11:52.824 13527-13572/? W/System.err: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.os.Handler.<init>(Handler.java:200)
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.os.Handler.<init>(Handler.java:114)
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.view.ViewRootImpl$ViewRootHandler.<init>(ViewRootImpl.java:3108)
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:3393)
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
01-28 18:11:52.824 13527-13572/? W/System.err:     at android.app.Dialog.show(Dialog.java:298)
01-28 18:11:52.824 13527-13572/? W/System.err:     at com.dominio.sti.api.SincronizarPredios.sincronizar(SincronizarPredios.java:62)
01-28 18:11:52.825 13527-13572/? W/System.err:     at com.dominio.sti.api.SincronizarPredios$ParserPredio.doInBackground(SincronizarPredios.java:167)
01-28 18:11:52.825 13527-13572/? W/System.err:     at com.dominio.sti.api.SincronizarPredios$ParserPredio.doInBackground(SincronizarPredios.java:96)
01-28 18:11:52.825 13527-13572/? W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
01-28 18:11:52.825 13527-13572/? W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
01-28 18:11:52.825 13527-13572/? W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
01-28 18:11:52.825 13527-13572/? W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
01-28 18:11:52.825 13527-13572/? W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
01-28 18:11:52.825 13527-13572/? W/System.err:     at java.lang.Thread.run(Thread.java:818)

This is the code:

public class SincronizarPredios {

    final String url = Constants.getApiUrl();
    final Date fecha = new Date();
    final PredioSQL predioSQL;
    final SincronizacionSQL sincronizacionSQL;
    final Context context;
    private ProgressDialog progressDialog;

    UserLocalStore userLocalStore;
    String token;

    public SincronizarPredios(Context appContext) {
        context = appContext;
        predioSQL = new PredioSQL(context);
        sincronizacionSQL = new SincronizacionSQL(context);
        userLocalStore = new UserLocalStore(context);

        progressDialog = new ProgressDialog(context);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setTitle("Conectando con el servidor...");
        progressDialog.setMessage("Obteniendo predios...");
        progressDialog.setCancelable(false);
    }

    public void sincronizar(String nextUrl, Integer zona_id) {

        String fullUrl = url + "predios/?zona=" + zona_id;

        token = userLocalStore.getApiKey();

        if (nextUrl != null) {
            fullUrl = nextUrl;
        }

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, fullUrl,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject jsonResponse) {
                        progressDialog.dismiss();
                        new ParserPredio().execute(jsonResponse);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        progressDialog.dismiss();
                    }
                }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("Content-Type", "application/json");
                params.put("Accept", "application/json");
                params.put("Authorization", "Token " + token);
                return params;
            }

        };

        VolleySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);
        progressDialog.show();
    }

    public class ParserPredio extends AsyncTask<JSONObject, Integer, Boolean> {
        private Integer porcAvance;
        private Float division;

        ProgressDialog pDialog;

        public ParserPredio() {
            pDialog = new ProgressDialog(context);
            pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            pDialog.setMessage("Guardando predios...");
            pDialog.setCancelable(true);
            pDialog.setMax(100);
        }

        @Override
        protected void onPreExecute() {

            pDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    ParserPredio.this.cancel(true);
                }
            });

            pDialog.setProgress(0);
            pDialog.show();
        }

        @Override
        protected Boolean doInBackground(JSONObject... params) {
            try {
                JSONObject jsonResponse = params[0];
                Integer count = jsonResponse.getInt("count");
                if (count > 0) {
                    JSONArray resultados = jsonResponse.getJSONArray("results");
                    String next = jsonResponse.getString("next");
                    division = (float) 100 / resultados.length();
                    for (int i = 0; i < resultados.length(); i++) {
                        if(isCancelled()){
                            break;
                        }
                        JSONObject jsonObject = (JSONObject) resultados.get(i);
                        Integer id_remota = jsonObject.getInt("id");
                        String nombre = jsonObject.getString("nombre");
                        String codigo_siscop = jsonObject.getString("codigo_siscop");
                        String codigo_sap = jsonObject.getString("codigo_sap");
                        Integer zona = jsonObject.getInt("zona");
                        Integer distrito = jsonObject.getInt("distrito");
                        Integer ubicacion = jsonObject.optInt("ubicacion", 0);
                        Boolean eliminado = jsonObject.getBoolean("eliminado");
                        Predio predio = predioSQL.getPredio(id_remota);
                        if (predio != null) {
                            predio.setNombre(nombre);
                            predio.setCodigo_siscop(codigo_siscop);
                            predio.setCodigo_sap(codigo_sap);
                            predio.setZona(zona);
                            predio.setDistrito(distrito);
                            predio.setUbicacion(ubicacion);
                            predio.setEliminado(eliminado);
                            predioSQL.updatePredio(predio);
                        } else {
                            predio = new Predio(null, id_remota, nombre, codigo_siscop, codigo_sap, zona, distrito, ubicacion, eliminado);
                            predioSQL.addPredio(predio);
                        }

                        porcAvance = (int) Math.round(i * division);
                        publishProgress(porcAvance);
                    }
                    if (next.equals("null")) {
                        sincronizacionSQL.setFechaSincronizacionModulo("predios", fecha);
                    } else {
                        sincronizar(next, null);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return true;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            int progreso = values[0];
            pDialog.setProgress(progreso);
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if(result)
            {
                pDialog.dismiss();
            }
        }

        @Override
        protected void onCancelled() {
            Toast.makeText(context, "Tarea cancelada!", Toast.LENGTH_SHORT).show();
        }
    }

}

I remain attentive to your comments, greetings.

    
asked by Marcelo 29.01.2016 в 01:34
source

1 answer

5
System.err: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

I suggest you perform the test using only Volley without having to create a Asynctask . Volley actually manages connections in independent threads, something similar to a Asynctask .

You use Volley or Asynctask but not both at the same time: Android Volley vs Asynctask (in English) a>

    
answered by 29.01.2016 / 01:54
source