17

I'm just learning about AsyncTask and want to use it as a separate class, rather then a subclass.

For example,

class inetloader extends AsyncTask<String, Void, String> {


    @Override
    protected String doInBackground(String... urls) {

        String response = "";

            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(urls[0]);
            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 e) {
                e.printStackTrace();
            }

        return response;
    }


    @Override
    protected void onPostExecute(String result) {
        Log.e("xx",result);
        // how do I pass this result back to the thread, that created me?
    }


}

and the main(ui) thread:

inetloader il = new inetloader();
il.execute("http://www.google.com");
//il.onResult()
//{
    ///do something...
//}

Thanks!

Roger Travis
  • 8,402
  • 18
  • 67
  • 94
  • 1
    Yes you can put it in a separate class, but most people don't because its purpose is usually a lot more clear if it's an inner class. If you're going to reuse it in lots of activities, go ahead. – keyser May 26 '12 at 17:46
  • I plan using it for different purposes, like if I call it from here, on result it should do that and that, if I call it from there, on result it should do something else... therefor if I'll keep it in the same class and have it call a function from that class on result, i'll have to make a new AsyncTask for every kind of action that it has to do onresult... – Roger Travis May 26 '12 at 17:52
  • use interface, just implement your activity by a interface and in onPostExcute() of Asyn class call mContext.implementedMethod(). – Anand Tiwari May 26 '12 at 17:54
  • Having it in a separate class also helps with version control & change management. – Kris Krause Dec 29 '13 at 14:53
  • 1
    BTW pls start your class names with a capital letter e.g. "InetLoader" - just basic Java convention. – Richard Le Mesurier Feb 03 '14 at 15:12

3 Answers3

34

Use a interface. Something like:

interface CallBackListener{
  public void callback();
}

Then do this in your UI thread:

inetloader il = new inetloader();
li.setListener(this);
il.execute("http://www.google.com");

In inetloader, add:

   CallBackListener mListener;

   public void setListener(CallBackListener listener){
     mListener = listener;
   }

then In postExecute(), do:

   mListener.callback();
Xi 张熹
  • 10,492
  • 18
  • 58
  • 86
  • Thanks, sound like it's the right direction to go. Especially if I could create a CallBackListener with the inetloader il = new inetloader(); and pass it into the il object. – Roger Travis May 26 '12 at 18:26
  • Hmm... strange, I don't have a "CallBackListener" in android v3, maybe it goes by some other name? – Roger Travis May 26 '12 at 18:28
  • 4
    @RogerTravis Yeah you have to create a CallBackListener interface yourself. And don't forget to add "implements CallBackLisnter" for your main UI class. – Xi 张熹 May 26 '12 at 18:29
  • ouch, it seems to give just one @Override public void callback() { for the UI thread. Is there a way for me to make multiple callbacks(){} on for each inetloader object I make? – Roger Travis May 26 '12 at 18:33
3

you can pass the activity instance to constructor and call activity function from there...
Like use interface :

public interface ResultUpdatable {

   public void setResult(Object obj);
   }

Implement this in the Activity and pass in the constructor of Async task and update the result from onPostExecute using setResult function.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
Dheeresh Singh
  • 15,643
  • 3
  • 38
  • 36
1
inetloader il = new inetloader();
il.execute("http://www.google.com");

String result = il.get();//put it in try-catch
                ^^^^^^^^ 

here you get result which is in onPostExecute(String result)

Samir Mangroliya
  • 39,918
  • 16
  • 117
  • 134
  • Not really :( I need some sort of an onResult listener, that will trigger once the AsyncTask finished, because querying some servers might take a while. On the other hand, putting the il.get() into a while(true) loop might sound too primitive, won't it? :) are there any better options? – Roger Travis May 26 '12 at 17:48
  • 2
    @Samir : This is a really bad idea. Whilst it does allow retrieving a result from the `AsyncTask`, using the `get()` method will block the UI thread and effectively turns what should be an asynchronous procedure into a synchronous one. The only valid use for the `get()` method I have ever come up with would be for 'chaining' two `AsyncTasks`. – Squonk May 26 '12 at 18:18