【问题标题】:Passing arguments to AsyncTask, and returning results将参数传递给 AsyncTask,并返回结果
【发布时间】:2011-05-10 21:13:34
【问题描述】:

我有一个应用程序进行一些长时间的计算,我想在完成时显示一个进度对话框。到目前为止,我发现我可以使用线程/处理程序来做到这一点,但是没有用,然后我发现了 AsyncTask

在我的应用程序中,我使用带有标记的地图,并且我已经实现了 onTap 函数来调用我定义的方法。该方法创建一个带有是/否按钮的对话框,如果单击是,我想调用AsyncTask。我的问题是如何将ArrayList<String> 传递给AsyncTask(并在那里使用它),以及如何取回一个新的ArrayList<String>,就像AsyncTask 的结果一样?

方法的代码如下:

String curloc = current.toString();
String itemdesc = item.mDescription;

ArrayList<String> passing = new ArrayList<String>();
passing.add(itemdesc);
passing.add(curloc);

ArrayList<String> result = new ArrayList<String>();

new calc_stanica().execute(passing,result);

String minim = result.get(0);
int min = Integer.parseInt(minim);

String glons = result.get(1);
String glats = result.get(2);

double glon = Double.parseDouble(glons);
double glat = Double.parseDouble(glats);

GeoPoint g = new GeoPoint(glon, glat);
String korisni_linii = result.get(3);

所以,如您所见,我想将字符串数组列表“传递”到AsyncTask,并从中获取“结果”字符串数组列表。 calc_stanica AssycTask 类看起来像这样:

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
    ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(baraj_mapa.this);
        dialog.setTitle("Calculating...");
        dialog.setMessage("Please wait...");
        dialog.setIndeterminate(true);
        dialog.show();
    }

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) {

        //Some calculations...

        return something; //???
    }

    protected void onPostExecute(Void unused) {
        dialog.dismiss();
    }

所以我的问题是如何在AsyncTask doInBackground 方法中获取“传递”数组列表的元素(并在那里使用它们),以及如何返回一个数组列表以在主方法中使用(“结果”数组列表)?

【问题讨论】:

    标签: android return android-asynctask progressdialog


    【解决方案1】:

    将您的方法更改为如下所示:

    String curloc = current.toString();
    String itemdesc = item.mDescription;
    ArrayList<String> passing = new ArrayList<String>();
    passing.add(itemdesc);
    passing.add(curloc);
    new calc_stanica().execute(passing); //no need to pass in result list
    

    并更改您的异步任务实现

    public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
    ProgressDialog dialog;
    
        @Override
        protected void onPreExecute() {
            dialog = new ProgressDialog(baraj_mapa.this);
            dialog.setTitle("Calculating...");
            dialog.setMessage("Please wait...");
            dialog.setIndeterminate(true);
            dialog.show();
        }
    
        protected ArrayList<String> doInBackground(ArrayList<String>... passing) {
            ArrayList<String> result = new ArrayList<String>();
            ArrayList<String> passed = passing[0]; //get passed arraylist
    
            //Some calculations...
    
            return result; //return result
        }
    
        protected void onPostExecute(ArrayList<String> result) {
            dialog.dismiss();
            String minim = result.get(0);
            int min = Integer.parseInt(minim);
            String glons = result.get(1);
            String glats = result.get(2);
            double glon = Double.parseDouble(glons);
            double glat = Double.parseDouble(glats);
            GeoPoint g = new GeoPoint(glon, glat);
            String korisni_linii = result.get(3);
        }
    

    更新:

    如果您想访问任务启动上下文,最简单的方法是就地覆盖 onPostExecute:

    new calc_stanica() {
        protected void onPostExecute(ArrayList<String> result) {
          // here you have access to the context in which execute was called in first place. 
          // You'll have to mark all the local variables final though..
         }
    }.execute(passing);
    

    【讨论】:

    • 感谢您的回答,但我还有一件事要问。如果我定义 int min = Integer.parseInt(minim);例如,在 AsyncTask 类 onPostExecute() 中,如何从我的主类方法访问它?当我像这样改变它时,我在主类方法中得到“min cannot be resolved”错误。
    • @Bojan Ilievski:只需将您的 min 变量设为全局变量即可。
    • AsyncTask.execute 上传递ArrayList 时出现以下错误:类型安全:为可变参数创建了一个ArrayList 的通用数组。
    • 非常感谢您发布这个!
    • 我也有类似的问题,但对我来说结果很重要。在您的示例中,我没有看到 result 如何回到主要方法。我只是不明白。你能解释一下吗?
    【解决方案2】:

    为什么要传递一个 ArrayList? 应该可以直接使用参数调用执行:

    String curloc = current.toString();
    String itemdesc = item.mDescription;
    new calc_stanica().execute(itemdesc, curloc)
    

    varrargs 是如何工作的,对吧? 制作一个 ArrayList 来传递变量是双重工作。

    【讨论】:

    • 我非常同意 Leander 的观点。无论如何要更改正确答案复选标记?
    【解决方案3】:

    我有点同意这一点。

    呼叫:

    new calc_stanica().execute(stringList.toArray(new String[stringList.size()]));
    

    任务:

    public class calc_stanica extends AsyncTask<String, Void, ArrayList<String>> {
            @Override
            protected ArrayList<String> doInBackground(String... args) {
               ...
            }
    
            @Override
            protected void onPostExecute(ArrayList<String> result) {
               ... //do something with the result list here
            }
    }
    

    或者您可以将结果列表设为类参数并将 ArrayList 替换为布尔值(成功/失败);

    public class calc_stanica extends AsyncTask<String, Void, Boolean> {
            private List<String> resultList;
    
            @Override
            protected boolean doInBackground(String... args) {
               ...
            }
    
            @Override
            protected void onPostExecute(boolean success) {
               ... //if successfull, do something with the result list here
            }
    }
    

    【讨论】:

      【解决方案4】:

      我不这样做。我发现重载 asychtask 类的构造函数更容易..

      公共类 calc_stanica 扩展 AsyncTask>

      String String mWhateveryouwantToPass;
      
       public calc_stanica( String whateveryouwantToPass)
      {
      
          this.String mWhateveryouwantToPass = String whateveryouwantToPass;
      }
      /*Now you can use  whateveryouwantToPass in the entire asynchTask ... you could pass in a context to your activity and try that too.*/   ...  ...  
      

      【讨论】:

        【解决方案5】:

        您可以收到这样的返回结果: AsyncTask

        @Override
        protected Boolean doInBackground(Void... params) {
            if (host.isEmpty() || dbName.isEmpty() || user.isEmpty() || pass.isEmpty() || port.isEmpty()) {
                try {
                    throw new SQLException("Database credentials missing");
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        
            try {
                Class.forName("org.postgresql.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        
            try {
                this.conn = DriverManager.getConnection(this.host + ':' + this.port + '/' + this.dbName, this.user, this.pass);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        
            return true;
        }
        

        接收类:

        _store.execute();
        boolean result =_store.get();
        

        希望它会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多