Question

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();
        }

    }


}
Was it helpful?

Solution

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 !"); 

}

}

OTHER TIPS

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.

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 the 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
                            }
                        }));

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

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top