Second response of the Web Service still has the value of the first

Asked

Viewed 46 times

1

The first thing I do in my application is send a message to the server, only to test if the connection is active and working. When receiving "ok" from the server I continue the application.

On the next screen I have to show a list of names, so I request the list. But it shows nothing the first time I start the screen, for something to appear I need to reload the screen, as when I turn the cell phone from portrait to landscape. It also appears if I put a button that forces the screen to be recreated.

After some tests I identified that the list was not appearing at first because the content she was receiving was "ok", which I get when making the connection check. I also identified that the Log responsible for showing what is coming from the requests made (in the function below attached) was correct, showing having received the list of names, but I also noticed that it is being shown after the Log that I put in the function that takes the information of the function below. How is that possible? I called a function and put an object to pick up the return, but the object has a value set before the return of my function. And this set value is the value of my last request.

I am using this library: Compile org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2

Example: the initial request takes the right answer, hers. Also because it is the >first, already the request of the list that is the 2nd picks the answer of the 1st >request. If I reload the page this means that a new >request is made, right? That would be the list request. Now the list appears, >but it appears because she got the answer to the second request, which is also >a list. The answer to the 3rd request was not used, and if I make a >4th request this will take the information from the 3rd and so on.

Below is the code used to make the requests.

public class HttpConnection {
    public static String getSetDataWeb(String url, String method, String data) throws URISyntaxException {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        String answer = "";

        try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpGet request = new HttpGet();
            // Setamos nossa URI
            request.setURI(new URI(url));
            // Executamos nossa transação HTTP
            HttpResponse response = httpclient.execute(request);
            // Pegamos o conteúdo advindo como resposta e inserimos em um InputStream
            answer = EntityUtils.toString(response.getEntity());
            Log.d("RESPOSTAhttp", answer);    
        }
        catch(NullPointerException e){ e.printStackTrace(); }
        catch(ClientProtocolException e){ e.printStackTrace(); }
        catch(IOException e){ e.printStackTrace(); }
        return(answer);
    }
}

Function sending the requested URL to httpConnection

public static String comandaDetalhes(final String numCartao) throws SQLException {
        new Thread(){
            public void run(){
                try{
                    n = HttpConnection.getSetDataWeb("http://192.168.1.20:7070/comanda/detalhes/"+numCartao, "", "");
                } catch(Exception e) {

                }
            }
        }.start();

        return n;
    }

Function that asks for the list of names for the function that uses httpConnection

public List<Conteudo> getComandaDetalhes(){
        conteudosL = new ArrayList<>();
        //--------INICIO PEGAR ComandaS---------
        if(chamadas == 0){
            try {
                String teste = ComandaDAO.comandaDetalhes(getIntent().getStringExtra("NumeroCartao"));
                Log.d("DETALHESCOMANDA", teste);
                if(teste != "Comanda inexistente!"){
                    JSONObject jo = new JSONObject(teste);
                    chamadas =0;
                    JSONArray jaBebidas = new JSONArray(jo.getString("bebidas"));
                    Log.d("RESPOSTADetalhesBebidas", String.valueOf(jaBebidas));
                    JSONArray jaPratos = new JSONArray(jo.getString("pratos"));
                    Log.d("RESPOSTADetalhesPratos", String.valueOf(jaPratos));
                    JSONArray jaComanda = new JSONArray(jo.getString("comanda"));
                    Log.d("RESPOSTADetalhesComanda", String.valueOf(jaComanda));

                    for(int i = 0; i<jaBebidas.length(); i++){
                        jo = jaBebidas.getJSONObject(i);
                        Conteudo conteudos = new Conteudo();
                        conteudos.setNome("x" + jo.getInt("quantidade_bebidas_comanda")
                                + "  " + jo.getString("nome_bebida") + "  R$ "
                                + jo.getDouble("preco_bebida"));
                        conteudosL.add(conteudos);
                    }
                    for(int i = 0; i<jaPratos.length(); i++){
                        jo = jaPratos.getJSONObject(i);
                        Conteudo conteudos = new Conteudo();
                        conteudos.setNome("x" + jo.getInt("quantidade_pratos_comanda")
                                + "  " + jo.getString("nome_prato") + "  R$ "
                                + jo.getDouble("preco_prato"));
                        Log.d("PratoAdicionado", conteudos.getNome());
                        conteudosL.add(conteudos);
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return conteudosL;
    }
  • 1

    The question is very confusing, simplify, put the code(s) where the problem occurs.

  • 1

    I tried to explain as much as I could, I edited it out to see if it looked better. It’s really confusing, but I don’t know how to explain it better.

1 answer

0


From what I’m seeing, in your capacity comandaDetalhes, you start a Thread but immediately returns this variable n, which is the variable that will receive the value of the answer when it ends, hoping that n already has the expected value (or that it will only return when it has). That’s not gonna happen.

On the second call to comandaDetalhes, the value of n returned the value that was assigned in the first answer, ie the "OK". What you need to understand here is that return n (probably) wheel before of

n = HttpConnection.getSetDataWeb("http://192.168.1.20:7070/comanda/detalhes/"+numCartao, "", "");

Asynchronous programming is different. It’s no use trying to turn a code that uses Threads into sequential code that won’t work. The best is to learn the paradigm of truth otherwise you will always fall into these traps.

In addition, there are other problems, the most alarming being the fact that you are swallowing exceptions. This is a huge shot in the foot, because when the bug appear (and he going appear), you will need all the information and error message you can get.

  • Whoa, thanks for the commentary, man. I really lack experience working with Threads as you may have noticed, but I did it this way because I couldn’t find another way to get information from Thread and return it. To be honest, this was my first time working with Threads. I would be very grateful if you could inform me how I can be accomplishing this. What you said makes sense yes. But do you have any idea what to do there to end the problem?

  • Also I do not understand very well why n continue with the value of before, the class I am using only to do the function, it does not run. Even this error occurs even when I use another class. For example: I have a class responsible for taking the data of the command and another to get drinks, but this error happens with the function of picking drinks, which is of another class, which has not been used for any request.

  • @Raphaelschmitt A guess: n is a static variable?

  • Got it, so no matter the number of instances of the class the variable will be 1 just because it is Static? Is that it? But that would explain why when I go in detail it picks up the previous answer, since actually the two functions (the confirmation and the Details list) belong to the same class and use the same variable. But, why does this keep happening when I use another function of another Class to pick up the values of the Web Service after I make the confirmation? Why then I wouldn’t be using the same variable Static.

  • But the other function of the other class does not call these functions that you have placed here to make the requests?

  • The only function it calls is that of httpConnection. It has other functions in the style of the command function Settings I have placed. It does not use the same Static variable that commands Settings use, but it still takes the information that would be in the Static variable of Commands.

  • Isn’t there a way I can force myself to wait for the return I want and then send no? Because I saw that in java you use Join(), but I tried and it didn’t work.

  • Java native threads, in general, are exaggerated on Android and bring more difficulties than they help. The Android environment has been designed with some restrictions in mind that do not match the use of Threads. The alternative is Asynctask. For comparison purposes, if you can understand more or less, take a look in that reply Soen that compares the same task using Threads and Asynctasks. Finally, I believe that there should be some higher level library, more focused on Android to do what you want.

  • As for your question of the reason: it is difficult to know without seeing the whole code. But a tip: avoid using static members when working with object orientation unless you have a great reason, especially on Android. This can bring you quite subtle and difficult to unravel bugs.

  • I get it, I’ll take a look at the use of Asynctasks to see if it solves my problem and also follow these tips of yours. Thank you!

  • Not at all. Good studies. :)

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.