1

I am working on an Android app.

This is one function inside a fragment:

private void guardar_paciente() {
        
        String tag_string_req = "req_login";
 
        StringRequest strReq = new StringRequest(Request.Method.POST,
                URL_CHECK, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                
                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    String id_paciente = jObj.getString("id");
                    String id_nhc = jObj.getString("nhc");
                    
                    if (!error) {
                  

                        editor2.putString("id_paciente", id_paciente);
                        editor2.putString("nhc", id_nhc);
                        editor2.apply();
                        
                    } else {
                        // Error in login. Get the error message
                      //  String errorMsg = jObj.getString("error_msg");

                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                 //   Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {

                Toast.makeText(getActivity(),
                        error.getMessage(), Toast.LENGTH_LONG).show();

            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting parameters to login url
                Map<String, String> params = new HashMap<String, String>();
                params.put("nombre_completo", nombre_completo);
                params.put("apellidos", apellidos);
                params.put("tel1", tel1);
                params.put("tel2", tel2);
                params.put("email", email);
                params.put("profesion", profesion);
                params.put("sexo", sexo);
                params.put("fecha_nacimiento", fecha_nacimiento);
                params.put("edad", edad);
                params.put("peso", peso);
                params.put("talla", talla);
                params.put("IMC", IMC);
                params.put("consentimiento", "1");
                params.put("clinica_paciente", clinica_actual);
                params.put("imagen_paciente", imagen_paciente);
                params.put("firma_paciente", numero+".JPG");
                params.put("DNI", DNI);
                params.put("direccion", direccion);
                params.put("raza", raza);


                return params;
            }

        };

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);


    }

What I need is to execute another function, abrirPaciente(), just after guardar_paciente() has finished all its methods and it is safe to change the UI. I have tried calling abrirPaciente() just after editor2.apply();, but the app crashes.

mvasco
  • 4,965
  • 7
  • 59
  • 120
  • 1
    you can [make use of callbacks](https://stackoverflow.com/questions/57330766/why-does-my-function-that-calls-an-api-return-an-empty-or-null-value) – a_local_nobody Oct 27 '20 at 19:31
  • 1
    trigger the callback as soon as you're done doing what you need to in onResponse, then you know it's done – a_local_nobody Oct 27 '20 at 19:32
  • @a_local_nobody, I will try to implement your proposal, thanks. – mvasco Oct 27 '20 at 19:39
  • 1
    no problem, you can definitely make use of callbacks to trigger another method there, but i'm not sure it will solve your problem of being safe to call on the UI, you might to make use of a runnable or some other mechanism to swap over to the main thread – a_local_nobody Oct 27 '20 at 19:41
  • @a_local_nobody, where should I put the interface definition? – mvasco Oct 27 '20 at 19:41
  • 1
    my java is very rusty, but i can try to make an example for you as an answer, it doesn't matter where you put the interface though – a_local_nobody Oct 27 '20 at 19:43

1 Answers1

1

Making use of callbacks :

public class foo {


    interface ExampleInterface {

        void finishedServiceCallNoErrors();
        void finishedServiceCallWithError(String error);
    }

     void guardar_paciente(ExampleInterface exampleInterface) {

        ...

        @Override
        public void onResponse(String response) {
            ....
            
            //there was no error
            exampleInterface.finishedServiceCallNoErrors();
            
            //there was an error
            exampleInterface.finishedServiceCallWithError("your error message here");
            
            ....
            
            
        }
        ...
        
    }
}

and an example of how you'd make use of this :

public class bar implements foo.ExampleInterface {

//simple example of how you'd use this
    private void callingIt() {
        new foo().guardar_paciente(this); //here, we can pass `this` because our class is implementing the interface
    }

//these now get returned to the class making use of the service call, so you can easily handle things here, instead of worrying about the logic in your service call response
    @Override
    public void finishedServiceCallNoErrors() {
        //TODO("Handle the response with no error");
        //your call completed and everything was fine, now do something else
    }

    @Override
    public void finishedServiceCallWithError(String error) {
        // TODO("Handle the response with an error")
        // there was an error, handle it here
    }
}

I'm not sure if this callback pattern will be safe to use if it's being triggered from a background thread, so for that you'd need to switch threads inside the callbacks, so inside finishedServiceCallNoErrors and inside finishedServiceCallWithError you'd potentially need like a Runnable, so you can make use of the main thread, or inside the onResponse of the service call, before triggering the callbacks, you could also change there to the main thread. You can find help with something like that here

a_local_nobody
  • 7,947
  • 5
  • 29
  • 51