malger
malger

Reputation: 173

AsyncTask - Return a String in postExecute to the Activity, which started the Async Task without blocking the UI Thread

I have an Activity, which starts an AsyncTask with an Implemented process dialog. That works fine! But i want to get a String return when the asyncTask has finished. So i have to return something in the onPostExecute - Method. That result(string) i want to grab in the Activity, which started the AsyncTask. I do not want to use .get() because it blocks the UI thread.

What do i have to write into onPostExecute and the Activity grab the string from doInBackground?

Thank you for any kind of help to solve this problem ;)

Now with Code:

class BgDL extends AsyncTask<String, Integer, String> {

    String finishString="";
    private Context context;

    ProgressDialog pdialog;

    public BgDL(Context cxt) {  //get the context (usually "this" from Activity / otherwise progressdialog wont show up!
        context = cxt;
        pdialog = new ProgressDialog(context);

    }


    @Override
    protected String doInBackground(String... strings) {
        OutputStream output;
        ByteArrayOutputStream baos = null;

        try {
            URL url = new URL(strings[0]);
            URLConnection connection = url.openConnection();
            connection.connect();

            int fileLength = connection.getContentLength();

            InputStream input = new BufferedInputStream(url.openStream());
            if (strings[1]=="toString") { // write byte to string  if a file is not given
                baos= new ByteArrayOutputStream();
                output = new DataOutputStream(baos);
            } else { //otherwise to string
                output = new FileOutputStream(strings[1]);
            }
            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
       }
       output.flush();
       output.close();
       input.close();
       if (strings[1]=="toString") { 
           finishString = baos.toString(); //
       } // only write byte to string if a file is not given
    } catch (Exception e) {log.d("ex",e.toString());
    }
    return finishString;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pdialog.setTitle("Please wait");
        pdialog.setIndeterminate(false);
        pdialog.setMax(100);
        pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pdialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        pdialog.setProgress(progress[0]);

    }
    protected void onPostExecute(String...finishString) {
        pdialog.dismiss();//!!!!!!!!!finishString i want to pass over to my Activity, which started this asynctask with .execute();
    }

Upvotes: 1

Views: 5596

Answers (3)

Jayanth N
Jayanth N

Reputation: 25

Create a class in your project which extends activity as shown below:

public class SomeClass extends Activity
{
    public void dataFromPostExecute(String data) 
    {
        System.out.println("in mainactivity");
    }
}

If you want a single thread for every activity, just create a class which extends Application

public class Async extends Application
{
private Socket globalSocket;

    @Override
    public void onCreate()
    {
        //socket = null;
    }

    public Socket getglobalSocket() 
    {
        return globalSocket;
    }

    public void setGlobalSocket(Socket globalSocket) 
    {
        this.globalSocket = globalSocket;
    }
}

In your socket class which extends Asynctask do the following:

public SocketClass extends AsyncTask<String,String,String>
{
    Async app;
    private SomeClass t_act;
    public SocketClass(SomeClass sct) 
    {
        t_act = sct;
        this.con = tst;
        app= ((Async)sct.getApplicationContext());
    }

    protected void onPostExecute(String data)
    {
        t_act.dataFromPostExecute(data);
    }
}

Then, in your activity extend SomeClass and do as shown below:

public class Activity1 extends SomeClass
{
    public void dataFromPostExecute(String data)
        {
            //do whatever you want. "data" of this method contains the values from                                     
              postexecute()
        }
}

Upvotes: 2

Simon Dorociak
Simon Dorociak

Reputation: 33515

What do i have to write into onPostExecute and the Activity grab the string from doInBackground?

When you are using AsyncTask then you can update your UI only on onProgressUpdate and onPostExecute method.

Your doInBackground() method returns some data and these data is going to onPostExecute method(it depends also how your generic are declared).

Generally, there is no another approaches how to do it.

You meant this:

AsyncTask a = new AsyncTask(Context);
a.execute(Input);

First means that your constructor looks like

public MyAsync(Context c) {
   this.c = c;
}

Second means that you declared your first generic type(assumption Input param is String) as

private class MyAsync extends AsyncTask<String, Void, String> {
  //...
}


And you want to update UI with String that returns doInBackground() method and merely place is onPostExecute method with IN parameter String that returns doInBackground().

protected void onPostExecute(String stringReturnedFromDoInBackground) 
{
   // some work
}


So if you want to do it in different way, change your application logic and use for example ResultReceiver with IntentService.

Upvotes: 1

Frank Sposaro
Frank Sposaro

Reputation: 8531

Your return value from doInBackground() is you formal in onPostExecute(). So you should just be able to pass it in.

Upvotes: 1

Related Questions