-1

First, in my application I'm calling that code :

                String login = e1.getText().toString();
                String password = e2.getText().toString();
                login = login.replace(" " , "");
                password = password.replace(" " , "");
                String a = FunkcjeAPI.zalogujSie(login, password);    
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);

It should call FunkcjeAPI.zalogujSie() - that method shows LogCat records and is returning back to my code where I show other LogCat records.

So correct order is :

07-27 20:51:48.610: A/Link(876): http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=&password=&imei=
07-27 20:51:48.630: A/Link(876): {"error":"You reached daily query limit !"}  

07-27 20:51:48.330: A/Uwaga !(876): null
07-27 20:51:48.335: A/Uwaga !(876): null
07-27 20:51:48.335: A/Uwaga !(876): null
07-27 20:51:48.340: A/Uwaga !(876): null
07-27 20:51:48.345: A/Uwaga !(876): null

But my application returning records in that order :

07-27 20:51:48.330: A/Uwaga !(876): null
07-27 20:51:48.335: A/Uwaga !(876): null
07-27 20:51:48.335: A/Uwaga !(876): null
07-27 20:51:48.340: A/Uwaga !(876): null
07-27 20:51:48.345: A/Uwaga !(876): null

07-27 20:51:48.610: A/Link(876): http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=&password=&imei=
07-27 20:51:48.630: A/Link(876): {"error":"You reached daily query limit !"}  

zalogujSie() function code :

public static String zalogujSie(final String nick, final String haslo)
    {
        final JSONParser jParser = new JSONParser();
        new Thread(new Runnable() {
        public void run() {     
        final String json = jParser.getJSONFromUrl("http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + nick + "&password=" + haslo + "&imei=");
        Handler mainHandler = new Handler(Looper.getMainLooper());
        mainHandler.post(new Runnable() {

            @Override
            public void run() {
                JSONObject jObject;
                try {

                    jObject = new JSONObject(json);
                    Log.wtf("Link", "http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + nick + "&password=" + haslo + "&imei=");
                    Log.wtf("Link", json);
                    String error = jObject.getString("error");
                    if(error == "You reached daily query limit !") { nadajWartosc("You reached daily query limit !"); }
                    if(error == "0") {nadajWartosc(jObject.getString("token"));}
                    if(error == "1") {nadajWartosc("1");}
                    if(error == "Invalid username") {nadajWartosc("Invalid username");}
                    if(error == "Invalid password") {nadajWartosc("Invalid password");}
                    if(error == "This user is already logged in !") {nadajWartosc("This user is already logged in !");}
                } catch (JSONException e1) {
                    e1.printStackTrace();
                }
                catch (NullPointerException e)
                {
                    e.printStackTrace();
                }

            }

        });   
            }}).start();

    return dozwrotu;
}

I don't know what is the reason of that. Now my application cannot work properly. I tried to add wait() method, but it didn't help me.

@EDIT

Michael Butscher gave me an suggestion to use an AsyncTask with ProgressDialog. It didn't help me. Maybe I have an error in my code (but compiler isn't returning any error) ?

Code in SignInActivit :

String login = e1.getText().toString();
                String password = e2.getText().toString();
                login = login.replace(" " , "");
                password = password.replace(" " , "");
                String[] argi = {login,password};
                String a = null;    
                    a = FunkcjeAPI.zalogujSie(this, login, password);               
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                Log.wtf("Uwaga !", a);
                if(a != "Invalid username" && a != "Invalid password" && a != "1")
                    t1.setText("Inserted incorrect data");
                if(a == "You reached daily query limit !")
                    t1.setText("You reached daily query limit !");
                if(a == "This user is already logged in !")
                    t1.setText("This user is already logged in !"); 

And in FunkcjeAPI :

public static String zalogujSie(Activity aktywnosc, final String nick, final String haslo)
    {
        String[] argumenty = {nick, haslo};
        new Logowanie(aktywnosc).execute(argumenty);

        return dozwrotu;


    }

public static class Logowanie extends AsyncTask<String, String, String>
    {
    Activity wywolujaceActivity;
    private ProgressDialog dialog;
    public Logowanie(Activity wywolujaceActivity) {
        this.wywolujaceActivity = wywolujaceActivity;
        dialog = new ProgressDialog(wywolujaceActivity);
    }

    protected void onPreExecute() {
        this.dialog.setTitle("Please wait...");
        this.dialog.setMessage("Getting data from server");
        this.dialog.show();
    }

    @Override
    protected String doInBackground(final String... argi) {
        final JSONParser jParser = new JSONParser();
        new Thread(new Runnable() {
        public void run() {     
        final String json = jParser.getJSONFromUrl("http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + argi[0] + "&password=" + argi[1] + "&imei=");
        Handler mainHandler = new Handler(Looper.getMainLooper());
        mainHandler.post(new Runnable() {

            @Override
            public void run() {
                JSONObject jObject;
                try {

                    jObject = new JSONObject(json);
                    Log.wtf("Link", "http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + argi[0] + "&password=" + argi[1] + "&imei=");
                    Log.wtf("Link", json);
                    String error = jObject.getString("error");
                    if(error == "You reached daily query limit !") { nadajWartosc("You reached daily query limit !"); }
                    if(error == "0") {nadajWartosc(jObject.getString("token"));}
                    if(error == "1") {nadajWartosc("1");}
                    if(error == "Invalid username") {nadajWartosc("Invalid username");}
                    if(error == "Invalid password") {nadajWartosc("Invalid password");}
                    if(error == "This user is already logged in !") {nadajWartosc("This user is already logged in !");}
                } catch (JSONException e1) {
                    e1.printStackTrace();
                }
                catch (NullPointerException e)
                {
                    e.printStackTrace();
                }

            }

    });   
            }}).start();
        return dozwrotu;
    }

    @Override
    protected void onPostExecute(String result) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }

    }


}
Community
  • 1
  • 1
TN888
  • 7,659
  • 9
  • 48
  • 84
  • 2
    Not related, but `if(error == "You reached daily query limit !")` should be `if(error.equals("You reached daily query limit !"))`. The first one will always return false. – Dalmas Jul 27 '13 at 19:19
  • what do you want to achieve in the first place ? you are using a new Thread to perform work off the UiThread ? well then no specific order is guaranteed. – Suau Jul 27 '13 at 19:41

5 Answers5

2

Android, like most GUI systems, works by setting up a message queue and running a loop in main thread which takes next message from queue and then processes it (usually by calling a method), then next message and so on (this is what classes Looper and Handler are for).

Your first snippet is executed now (I assume) in main thread. It calls zalogujSie() which starts a new thread which in turn places a Runnable at the end of this message queue. But this can only be run after current method (containing your first snippet) was executed and all previous messages in the queue were processed.

Michael Butscher
  • 10,028
  • 4
  • 24
  • 25
  • @Ty221 Answer extended – Michael Butscher Jul 28 '13 at 09:43
  • Ok, thank you. can you tell me what should I do to be that in correct order ? Without that my application doesn't work – TN888 Jul 28 '13 at 09:45
  • 1
    Look at `AsyncTask` to do things in a separate thread in conjuction with `ProgressDialog` to block the GUI without blocking the main thread. Convert `zalogujSie()` to an `AsyncTask` and execute it from your first snippet. – Michael Butscher Jul 28 '13 at 09:52
  • Ok, thanks. I never used AsyncTask - can you write something more about that in your answer ? – TN888 Jul 28 '13 at 09:53
  • @Ty221 The snippet in this question http://stackoverflow.com/q/14299846/987358 and this answer http://stackoverflow.com/a/4538370/987358 show examples how to use `AsyncTask` with `ProgressDialog` – Michael Butscher Jul 28 '13 at 10:48
  • @Ty221 It may be better to move the code after call to `zalogujSie()` at the end of `onPostExecute()` – Michael Butscher Jul 29 '13 at 12:32
2

AsyncTask's doInBackground() method already runs in a separate thread. From your Edit, you are starting another thread from inside of doInBackround(). This is not necessary.

It seems that you want the code following the execution of your AsyncTask to wait for its completion. If this is the case, it would be better to use the onPostExecute() method of the AsyncTask.

Your SignInActivit should look like:

String login = e1.getText().toString();
String password = e2.getText().toString();
login = login.replace(" " , "");
password = password.replace(" " , "");

// Now, execute your AsyncTask, no need for `zalogujSie()`
new Logowanie(this, login, password).execute();

You don't need the intermediary step of calling zalogujSie(). You can pass the login & password as arguments to the constructor. AsyncTask as:

public static class Logowanie extends AsyncTask<Void, Void, Void> {

    Activity wywolujaceActivity;
    private ProgressDialog dialog;
    private String user, pass, error;

public Logowanie(Activity wywolujaceActivity, login, password) {
    this.wywolujaceActivity = wywolujaceActivity;
    dialog = new ProgressDialog(wywolujaceActivity);

    this.user = login;
    this.pass = password;
}

protected void onPreExecute() {
    this.dialog.setTitle("Please wait...");
    this.dialog.setMessage("Getting data from server");
    this.dialog.show();
}

@Override
protected String doInBackground(Void... nothing) {

    error = "";

    final JSONParser jParser = new JSONParser();        

    final String json = jParser.getJSONFromUrl("http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + user + "&password=" + pass + "&imei=");

    JSONObject jObject;

    try {
        jObject = new JSONObject(json);

        Log.wtf("Link", "http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + user + "&password=" + pass + "&imei=");

        Log.wtf("Link", json);

        error = jObject.getString("error");

        if(error.equals("You reached daily query limit !")) { nadajWartosc("You reached daily query limit !"); }

        if(error.equals("0")) {nadajWartosc(jObject.getString("token"));}

        if(error.equals("1")) {nadajWartosc("1");}

        if(error.equals("Invalid username")) {nadajWartosc("Invalid username");}

        if(error.equals("Invalid password")) {nadajWartosc("Invalid password");}

        if(error.equals("This user is already logged in !")) {nadajWartosc("This user is already logged in !");}

    } catch (JSONException e1) {
        e1.printStackTrace();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }

    return null;
}

@Override
protected void onPostExecute(Void result) {
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }

    Log.wtf("Uwaga !", a);
    Log.wtf("Uwaga !", a);
    Log.wtf("Uwaga !", a);
    Log.wtf("Uwaga !", a);
    Log.wtf("Uwaga !", a);

    // You had an "and"ing these conditions instead of "or"ing which would always return false.      
    if(error.equals("Invalid username") || error.equals("Invalid password") || error.equals("1"))
        t1.setText("Inserted incorrect data");

    if(error.equals("You reached daily query limit !"))
        t1.setText("You reached daily query limit !");

    if(error.equals("This user is already logged in !"))
        t1.setText("This user is already logged in !"); 

}

}

Vikram
  • 51,313
  • 11
  • 93
  • 122
1

Your network request is happening asynchronously to the logging you declare. To fix this, you need to wait until the network task is complete. A simple way to do this is through the use of my droidQuery library:

String login = e1.getText().toString();
String password = e2.getText().toString();
login = login.replace(" " , "");
password = password.replace(" " , "");
$.ajax(new AjaxOptions().url("http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + login + "&password=" + password + "&imei=")
                        .dataType("json")
                        .type("GET")
                        .success(new Function() {
                            @Override
                            public void invoke($ droidQuery, Object... params) {
                                //the request was successful
                                String a = params[0].toString();
                                Log.wtf("Uwaga !", a);//This will print what you are expecting
                            }
                        })
                        .error(new Function() {
                            @Override
                            public void invoke($ droidQuery, Object... params) {
                                //there was an error
                                AjaxError error = (AjaxError) params[0];
                                Log.e("Uwaga !", "Error " + error.status + ": " + error.reason);
                            }
                        })
                        .complete(new Function() {
                            @Override
                            public void invoke($ droidQuery, Object... params) {
                                //your network request has completed
                            }
                        }));
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Phil
  • 35,852
  • 23
  • 123
  • 164
0

your zalogujSie method uses a new Thread, so the method runs asynchronously ... no order is guaranteed at this point.

Suau
  • 4,628
  • 22
  • 28
0

you can wait() a object before the thread begins,

and inside the thread , when it ends, notify() that object.

the original thread can keep on going

MengMeng
  • 1,016
  • 6
  • 11