【问题标题】:Android: Multiple params in AsynctaskAndroid:Asynctask 中的多个参数
【发布时间】:2012-07-04 21:49:12
【问题描述】:

我需要将两个参数(lv 和位置)传递给 Asynctask doInBackground 方法,但我不知道该怎么做...

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

谢谢!

编辑:

我有一个列表视图。如果您单击项目播放声音(来自 Internet)。

我想用 Asynctask 显示一个 progressDialog。

在 doInBackground 方法中,我有 itemOnClick:

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

因此我需要传递 lv 和位置。

【问题讨论】:

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

标签: android android-asynctask


【解决方案1】:

尝试在您的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 中将其关闭。

【讨论】:

  • 不太确定,但由于某种原因,这看起来是一种不好的做法。
  • 这肯定是一种不好的做法,除非您将成员字段设置为 final 或 volatile,因为构造函数在与 doInBackground 方法不同的线程中运行,(或者在远非最佳的同步块中访问这些字段)。
  • 正如我之前所说,这不是一个坏习惯,因为它在文档中,但是由您来处理那些您需要更改您正在传递的参数的值或者如果您不是做任何事情,但将它们用作参考。
  • 是的,它在文档上 O_o 见developer.android.com/reference/android/os/… 一些人知道这种做法
【解决方案2】:

就像this 回答中所说的,您可以使用对象数组作为参数:

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 在他对您的 OP 的评论中提到的那样,将 ListView 传递给 AsyncTask 并不是一个好主意。因此,这段代码展示了如何将多个参数传递给 AsyncTask,但在您的情况下使用它并不是一个好主意。

    【讨论】:

    • 是的,您的代码可以工作,但请阅读我对 OP 问题的评论。
    • 好点,我应该提一下 :) 我会将其编辑到我的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 2015-09-25
    • 2015-08-05
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多