Android: Asynctask中传递多个参数

3

我需要向Asynctask doInBackground方法传递两个参数(lv和position),但我不知道如何做...

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

感谢您的信任!

编辑:

我有一个 ListView。如果您单击其中一个项目,则播放互联网中的声音。

我想使用 Asynctask 显示 progressDialog。

在 doInBackground 方法中,我有 itemOnClick:

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

因此我需要传递lv和position参数。

1
我不确定为什么你想把一个 ListView 传递到 AsyncTaskdoInBackground(...) 方法中,但基本上你真的不想这样做。ListView 可能是 Activity 内容视图的一部分,如果你从运行 doInBackground(...) 代码的 Thread 中触摸它,你将会得到一个异常抛出并且你的应用程序将会崩溃。 - Squonk
3
好的,显然你没有理解我的评论或者你不相信我。无论如何,我还是再说一遍:试图从不同的线程中访问主线程(即UI线程)中的对象,比如在AsyncTaskdoInBackground(...)方法中访问,会导致应用程序崩溃。我真的不知道为什么你想使用AsyncTask来播放声音——如果你想要背景音乐,可以使用一个Service。或者,如果你坚持使用AsyncTask,将ListView选择监听器放在Activity中,并将HashMap作为参数传递给AsyncTask - Squonk
3个回答

22

尝试在你的AsyncTask中创建一个构造函数,每当你创建对象时,可以传递参数。 像这样:

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

    }

然后您只需调用asynctask.execute();

编辑:在阅读了您更新的问题后,我同意Squonk使用服务来播放背景声音;另外,您可以在启动AsynkTask之前显示进度对话框(如果此任务是无限期的),并在postexecute上解除它。


不太确定,但出于某种原因,这看起来像是不好的做法。 - User
除非您将成员字段设置为final或volatile,否则这是一种不好的做法,因为构造函数在不同的线程中运行于doInBackground方法之外(或者在同步块中访问这些字段,但这远非最佳选择)。 - Tomasz Gawel
正如我之前所说,这不是一种坏的做法,因为它在文档中有说明,但是当你需要改变传递的参数的值或者仅仅使用它们作为参考时,这就取决于你自己了。 - Raykud
是的,它在文档中 O_o,请参见 https://developer.android.com/reference/android/os/AsyncTask#public-constructors 一些人知道这种做法。 - arxzel

8

就像在这个答案中所说,你可以使用对象数组作为参数:

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

请务必将它们转换为正确的对象类型

下面是调用AsyncTask的方法:

LoadSound loadSound = new LoadSound();
loadSound.execute(lv, position);

3
您可以创建一个内部类来保存您的参数,例如:
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);

编辑

正如Squonk在您的原始帖子中所提到的,将ListView传递给AsyncTask并不是一个好主意。因此,这段代码展示了如何向AsyncTask传递多个参数,但在您的情况下使用它并不是一个好主意。


是的,你的代码可以运行,但请阅读我的评论关于问题原始发布者的问题。 - Squonk
好的,我应该提到那个 :) 我会将它编辑到我的答案中。 - Jan-Henk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接