0

I'm using this AsyncTask for calling the skype page https://login.skype.com/json/validator?new_username=username for understand if a certain skype contact already exsists.

public class SkypeValidateUserTask extends AsyncTask<String, Void, String>{

protected String doInBackground(String...urls){
    String response = "";
    for(String url:urls){
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try{
            HttpResponse execute = client.execute(httpGet);
            InputStream content = execute.getEntity().getContent();

            BufferedReader buffer = new BufferedReader(new InputStreamReader(content));

            String s="";
            while((s=buffer.readLine()) != null){
                response+=s;
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
    return response;
}

public void onPostExecute(String result){
    String status="";
    try{    
        JSONObject obj=new JSONObject(result);
        status=obj.getString("status");
    }catch(Exception ex){
        ex.printStackTrace();
    }
    //Log.i("RISULTATO: ","STATO: "+status);

}
}

The main activity call this task for getting skype validation user result. The code is:

String skype = "name.surname.example";  

if(!skype.equalsIgnoreCase("")){
            // check if the skype contact exists
            SkypeValidateUserTask task = new SkypeValidateUserTask();
            task.execute(new String[] {"https://login.skype.com/json/validator?new_username="+skype});  

                // here I need to obtain the result of the thread

        }

My problems are:

  1. I need to get the result of the task (the String status) in the main activity.

  2. After the task.execute call, the next code in main activity is executed without wait for result returned from asynctask.

GVillani82
  • 17,196
  • 30
  • 105
  • 172

7 Answers7

2

It is dengerious to use get() method to get the result from async task because It blocks the UI Thread. use This Thread where I provided a reusable solutionCallback mechanism to get result from async thread without blocking UI Thread

I have implemented that with the help of lapslaz

public JsonData(YourActivityClass activity) 
{
    this.activity=activity;
    mProgressDialog = new ProgressDialog(activity);

}
protected void onPostExecute(String jsondata) {
    if (mProgressDialog != null || mProgressDialog.isShowing()){
        mProgressDialog.dismiss();
    }
    if(jsondata!=null) {
        activity.yourcallback(jsondata)
    }

}

And define the yourcallback() in YourActivityClass

private void yourcallback(String data) {
    jsonRecordsData=data;
    showRecordsFromJson();

}
Community
  • 1
  • 1
Pragnani
  • 20,075
  • 6
  • 49
  • 74
1

Start your AsyncTask on the main thread. In the preExecute method of the AsyncTask, you can start a ProgressDialog to indicate to the user that you're doing something that takes a few seconds. Use doInBackground to perform the long-running task (checking for valid Skype username, in your case). When it is complete, onPostExecute will be called. Since this runs on the UI thread, you can handle the result and perform further actions depending on it. Don't forget to close the ProgressDialog in onPostExecute.

WeNeigh
  • 3,489
  • 3
  • 27
  • 40
  • Ok, but how can I pass the String status from my background Task to UI-Thread? The onPostExecute can't access to my main activity cause is in another class (SkypeValidateUserTask ) – GVillani82 Feb 06 '13 at 16:49
  • My AsyncTask can't view Progress dialog created in main activity. so I can't call dialog.dismiss(); – GVillani82 Feb 06 '13 at 17:03
  • There are several ways you could handle that - Refactor the code to be run after SkypeValidateUserTask into the onPostExecute itself, or notify your activity of the result in onPostExecute. – WeNeigh Feb 06 '13 at 17:06
  • As for the ProgressDialog, you could just create it in onPreExecute! – WeNeigh Feb 06 '13 at 17:07
  • I trid using dialog.show in onPreExecute and dialog.dismiss onPostExecute, but my UI-Thread does not stop its execution. – GVillani82 Feb 06 '13 at 17:27
  • The UI thread will NOT stop its execution. Use ProgressDialog.show(...) in onPreExecute and hold on to the object in a field of the AsyncTask and dismiss it in onPostExecute – WeNeigh Feb 06 '13 at 17:49
0

That's why asyncTask is here. You can not make a blocking function call in UI thread because that will make your app unresponsive.

YankeeWhiskey
  • 1,522
  • 4
  • 20
  • 32
0

OnPostExcute Method is called on the UI/Main thread. you need to move your logic there to continue analyzing the result.

Mr.Me
  • 9,192
  • 5
  • 39
  • 51
  • @Joseph82 That is unachievable. You must process the result later when `onPostExcute` is called – YankeeWhiskey Feb 06 '13 at 16:38
  • You don't have to wait for it, because onPost will actually be excuted in the main thread , so why would you wait, just move your logic to onPost excute – Mr.Me Feb 06 '13 at 16:39
0

If your AsyncTask is an inner class of your main activity then you can just call a function in the main activity and pass it the result

Since it looks like it isn't, you can create constructor in your Async and pass it the Context from your main activity so you can pass the variable back to main activity

Also, the purpose of the AyncTask is to not block your UI thread, put your logic in a separate function that the AsyncTask will call

codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • 1
    Using a non-static inner AsyncTask is a bad idea because it can lead to memory leaks in case of configuration changes (screen orientation, keyboard etc). Holding on to the Activity in the AsyncTask can again lead to the Activity instance being leaked. Refer http://stackoverflow.com/questions/3357477/is-asynctask-really-conceptually-flawed-or-am-i-just-missing-something – WeNeigh Feb 06 '13 at 17:51
0

You need to implement a call-back mechanism in your AsyncTask. So instead of this:

task.execute(...);
// use results of task

Your structure should be:

    task.execute(...);
    // go do something else while task has a chance to execute

public void statusAvailable(String status) {
    // use results of task
}

and in onPostExecute:

public void onPostExecute(String result) {
    . . .
    status=obj.getString("status");
    activity.statusAvailable(status);
}
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
0

Getting the result out of the AsyncTask is easy . . . just the Google docs don't make it clear how to do it. Here's a quick run down.

task.execute(params);

will start the AsyncTask and pass to the doInBackground method whatever parameters you include. Once doInBackground finishes, it passes the result of its functions to onPostExecute. One would think that onPostExecute would be able to just return whatever you sent it. It doesn't. To get the result of doInBackground, which was sent to onPostExecute you need to call

task.get();

the .get() method automaticlly waits until the task has completed execution and then returns whatever the result of onPostExecute is back to the UI thread. You can assign the result to whatever variable you want and use normally after that - for example

JSONObject skypeStuff = task.get()

Put another way - just like the AsynTask does not start on it's own, it does not return on its own. The same way you need to .execute() from the UI thread, you need to call .get() from the UI thread to extract the result of the task.

Rarw
  • 7,645
  • 3
  • 28
  • 46