3

I need to pass two params (lv and position) to a Asynctask doInBackground method but I don't know how do it...

LoadSound.execute(lv,position)
class LoadSound extends AsyncTask<**[ListView,int]**, String, String>

thanks!

EDIT:

I have a listView. If you click in an item play sound (from Internet).

I would like show a progressDialog with Asynctask.

In the doInBackground method I have the itemOnClick:

HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);

for this reason I need to pass lv and position.

piokuc
  • 25,594
  • 11
  • 72
  • 102
user1364684
  • 800
  • 2
  • 8
  • 28
  • 1
    I'm not sure why you want to pass a `ListView` into the `doInBackground(...)` method of an `AsyncTask` but basically you really don't want to do that. The `ListView` is presumably part of an `Activity` content view and if you touch it from the `Thread` that runs the `doInBackground(...)` code, you will get an exception thrown and your app will crash. – Squonk Jul 04 '12 at 22:02
  • 3
    OK, you obviously didn't understand my comment or you don't believe me. I'll say it again anyway - trying to access objects that are part of the main (UI) thread from a different thread, e.g., `doInBackground(...)` of an `AsyncTask`, will fail and cause your app to crash. I really don't know why you'd want to use an `AsyncTask` to play sounds anyway - if you want background music, for example, use a `Service`. Alternatively if you insist on using `AsyncTask`, have the `ListView` selection listener in your `Activity` and pass your `HashMap` as the parameter to `AsyncTask`. – Squonk Jul 04 '12 at 22:56

3 Answers3

22

try creating a constructor within your AsyncTask and whenever you create your object you can pass the parameters. Something like this:

MyAsyncTask asynctask = new MyAsyncTask(10, true, myObject);
//this is how you create your object

 public class MyAsyncTask extends AsyncTask<Void, Void, Void>{

        int a;
        boolean b;
        Object c;

        public MyAsyncTask(int a, boolean b, Object c){
            this.a = a;
            this.b = b;
            this.c = c;
        }

        @Override
        protected Void doInBackground(Void... params) {
            if(b)
                c = a;
            return null;
        }

    }

and then you can just call asynctask.execute();

Edit: After reading your updated question I agree to Squonk to use a Service for example to play a background sound; also you can show a progress dialog before launching your AsynkTask (if this one is indefinetly) and dismiss it on your postexecute.

Raykud
  • 2,488
  • 3
  • 21
  • 41
  • Not quite sure, but for some reason, this looks like bad practice. – User Jul 04 '12 at 21:56
  • Surely it is a bad practice UNLESS you make member fields final or volatile because constructor runs in different thread than doInBackground method, (alternatively access these fields in synchr block which is far from optimal). – Tomasz Gawel Jul 05 '12 at 01:28
  • as I stated before, its not a bad practice since its on the documentation, however its up to you to handle those cases where you need to change the value of the parameter you are passing or if you arent doing anything but using them as reference. – Raykud Jul 05 '12 at 15:52
  • Yeah, its on the documentation O_o see https://developer.android.com/reference/android/os/AsyncTask#public-constructors a few people know that practice – arxzel Jan 31 '19 at 20:56
8

like said in this answer you could use an array of Objects as parameter:

private class LoadSound extends AsyncTask<Object, String, String> {
    @Override
    protected void doInBackground(Object... params) {
        ListView lv = (ListView) params[0];
        int position = (Integer) params[1];
    }
    // ...
}

Be sure to cast them to the correct object type

And this is how to call the AsyncTask:

LoadSound loadSound = new LoadSound();
loadSound.execute(lv, position);
Community
  • 1
  • 1
Dediqated
  • 901
  • 15
  • 35
3

You could create an inner class that holds your parameters, something like this:

public static class LoadSoundParam {
    public ListView lv;
    public int position;
}

class LoadSound extends AsyncTask<LoadSoundParam, String, String> {
    ...
}

LoadSoundParam param = new LoadSoundParam();
param.lv = lv;
param.position = position;

loadsound.execute(param);

EDIT

As Squonk mentions in his comment to your OP, it is not a good idea to pass a ListView into an AsyncTask. So this code shows how to pass multiple parameters to an AsyncTask, but it is not a good idea to use it in your situation.

Jan-Henk
  • 4,864
  • 1
  • 24
  • 38