GVillani82
GVillani82

Reputation: 17439

Android: Communication and coordination between UI-thread and other thread

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.

Upvotes: 0

Views: 866

Answers (7)

Pragnani
Pragnani

Reputation: 20155

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

}

Upvotes: 2

Rarw
Rarw

Reputation: 7663

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.

Upvotes: 0

WeNeigh
WeNeigh

Reputation: 3509

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.

Upvotes: 1

Ted Hopp
Ted Hopp

Reputation: 234857

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

Upvotes: 0

codeMagic
codeMagic

Reputation: 44571

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

Upvotes: 0

Mr.Me
Mr.Me

Reputation: 9286

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

Upvotes: 0

YankeeWhiskey
YankeeWhiskey

Reputation: 1582

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

Upvotes: 0

Related Questions