【问题标题】:How to return ArrayList from AsyncTask to another class?如何将 ArrayList 从 AsyncTask 返回到另一个类?
【发布时间】:2014-03-11 12:31:28
【问题描述】:

我想使用 AsyncTask 从服务器获取 Ftp 文件夹列表,并将文件夹名称 ArrayList 返回到主类并更新微调器适配器。

在主课中,我得到了带适配器的微调器

//the array i want to update in AsyncTask
static ArrayList<String> directoriesTeacher = new ArrayList<String>();

//The adapter
createfile_spinTeacher = (Spinner) findViewById(R.id.createfile_spinTeacher);   
final ArrayAdapter<String> dataAdapterTeacher = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,directoriesTeacher);
dataAdapterTeacher.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
createfile_spinTeacher.setAdapter(dataAdapterTeacher);

AsyncTask 中的一个:

    package com.nedoGarazas.learnanylanguage;

    import java.util.ArrayList;

    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPFile;
    import org.apache.commons.net.ftp.FTPReply;

    import android.os.AsyncTask;
    import android.util.Log;

    public class FtpTeacher extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
    private static final String TAG = "MyFTPClient";
    public FTPClient mFTPClient = null; 
     ArrayList<String> ftpTeacher = new ArrayList<String>();
    @Override
    protected ArrayList<String> doInBackground(ArrayList<String>... params) {
        {                       
            try {
                mFTPClient = new FTPClient();
         // connecting to the host
                mFTPClient.connect("host.ftp.com", 21);

          // now check the reply code, if positive mean connection success
                if     (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
      // login using username & password
                    boolean status = mFTPClient.login("admin", "admin");
                    if(status == true){

                            try {
                                FTPFile[] ftpFiles = mFTPClient.listFiles("/Wordsftp/");
                                int length = ftpFiles.length;

                                for (int i = 0; i < length; i++) {
                                    String name = ftpFiles[i].getName();
                                    boolean isDirectory = ftpFiles[i].isDirectory();

                                    if (isDirectory) {
//adding to arraylist
                                        ftpTeacher.add(name);
                                        Log.i(TAG, "Yra : " + name);
                                    }
                                    else {
                                        Log.i(TAG, "Directory : " + name);

                                }
                             }
                            } catch(Exception e) {
                            e.printStackTrace();
                        }


                    mFTPClient.setFileType(FTP.ASCII_FILE_TYPE);
                    mFTPClient.enterLocalPassiveMode();


}
                }
} catch(Exception e) {
Log.d(TAG, "Error: could not connect to host ");
}
return ftpTeacher;
} 
            }

    protected ArrayList<String>[] onPostExecute(ArrayList<String>... result) {
        ////How to return?

    }

    }

那么我应该如何用主类中的 ArrayList 替换 AsyncTask 中的 arraylist 并动态更新微调器更新程序?

【问题讨论】:

  • 在 AsynTask 的 onPost 方法中将列表的值复制到活动列表中。
  • 我该怎么做?我不知道如何正确使用 AsyncTask

标签: java android android-asynctask ftp-client


【解决方案1】:

-- 伪代码--

如下创建一个自定义interface

public interface IAsyncTask {

    void IAmFinished(ArrayList<Object> arrayList);

}

给你的AsyncTask添加一个构造函数:

private IAsyncTask asyncTaskListener;

public MyAsyncTask(IAsyncTask asyncTaskListener){
     this.asyncTaskListener = asyncTaskListener;
}

在您的PostExecute 中的AsyncTask

public void onPostExecute(List<String> list) {
    asyncTaskListener.IAmFinished(list);
}

在您的Activity 中启动您的AsyncTask

MyAsyncTask asyncTask = new MyAsyncTask(this);
asyncTask.execute(..);

实现接口:

public class MyActivity implements IAsyncTask

实现方法:

public void IAmFinished(ArrayList<Object> list){
    // Do whatever you want with your returned object
}

【讨论】:

    【解决方案2】:

    您已经将 ArrayList 设为 静态,也将其设为公开。并通过您的班级名称使用它。并在 onPostExecute() 中填充您的 ArrayList;喜欢

         protected void onPostExecute(ArrayList<String>... result) {
    
        if(YourClassName.directoriesTeacher.size()>0)
         {
           YourClassName.directoriesTeacher.clear();
          }
    
          YourClassName.directoriesTeacher.addAll(result);
    
         }
    

    【讨论】:

    • 以及如何添加我在 DoInBackgroud 中获得的文件夹名称?
    • 一个建议,当您使用您的数据时清除您的列表。否则,每当您再次调用 aync 任务时,数据可能会重复
    • 以及如何更新 dataAdapterTeacher.notifyDataSetChanged();在我的主课上?
    【解决方案3】:

    我假设您在获取数据时不想要微调器,而是用后台任务中的数据填充微调器?从 AsyncTask 返回数据通常依赖于这种模式,使用接口。

    1) 创建一个接口,以便您可以回发结果:(您可以在单独的文件中创建这个类,也可以在任一类中声明它)

    public interface ReturnData{
        void handleReturnData(ArrayList<String> list);
    }
    

    2) 在你的主类中实现 ReturnData 接口:

    public class MyMainClass extends Activity implements ReturnData{
    
        AsyncTask ftpTeacher = new FtpTeacher();//declare your async task
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            ftpTeacher.returnData = this; //set this class as receiver for return data
            //set up adapters etc, just like you do now
            ...
        }
    
    
    
         //Your new data will be returned here - update your current adapter with new list
         @Override
         void handleReturnData(ArrayList<String> list){
              directoriesTeacher = list; //assign new data
              dataAdapterTeacher.notifyDataSetChanged();  //Tell adapter it has new data = forces redraw
         }
    
         ....
    }
    

    3) 在您的 AsyncTask 类中:

    public class FtpTeacher extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
        private static final String TAG = "MyFTPClient";
        public FTPClient mFTPClient = null; 
        ArrayList<String> ftpTeacher = new ArrayList<String>();
        public ReturnData returnData; // <--- PUBLIC
        ...
     }
    

    4) 最后,返回数据:

    protected ArrayList<String>[] onPostExecute(ArrayList<String>... result) {
        returnData.handleReturnData(result);
    }
    

    【讨论】:

      【解决方案4】:

      在您调用 AsyncTask 的 main 中,覆盖 onPostExecute 方法并将您的适配器内容放在那里。它在 UI 线程上被调用,所以它被保存了。

      所以在你调用 AsyncTask 的地方,做

      new FTPTeacher() {
      
       public void onPostExecute(List<String> list) {
      
           createfile_spinTeacher = (Spinner) findViewById(R.id.createfile_spinTeacher);   
           final ArrayAdapter<String> dataAdapterTeacher = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,list);
           dataAdapterTeacher.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
           createfile_spinTeacher.setAdapter(dataAdapterTeacher);
      
       }
      
      }.execute();
      

      【讨论】:

        【解决方案5】:

        onPostExecute 方法在 UI 线程中运行。您可以将 postexecute() 中的结果分配给 main 方法中的数组列表。通过调用 notifydatasetChanged 来更新适配器以更新您的列表视图。

        【讨论】:

          【解决方案6】:

          实现 listener 传递 ArrayList 并使用此侦听器返回您的 ArrayList

          public interface TaskListener {
              public void onSuccess(ArrayList<String> result);
          
          }
          

          在调用异步任务以执行操作时,创建TaskListener 的实例,如下所示:

          TaskListener listener = new TaskListener() {
          
                  @Override
                  public void onSuccess(ArrayList<String> result) {
                         // Your result will come here
                  }
              };
          

          将此listenerobject 作为参数传递给异步任务构造函数。并在异步任务本身中创建TaskListener 的全局实例。将构造函数中的TaskListener 参数分配给全局实例。

          然后在异步任务类的onPostExecute中:

          protected ArrayList<String>[] onPostExecute(ArrayList<String>... result) {
                  this.taskListenerGlobalInstance(result); // this will invoke the call back method 
          
              }
          

          【讨论】:

            【解决方案7】:

            在您的 AsyncTask 中,您可以拥有一个与您的活动具有相同类别的成员 (MyActivity m_activity)。

            在您的 AsyncTask 构造函数中,设置一个 MyActivity 参数并将其记录在 m_activity 中。

            在您的 onPostExecute 中运行刷新微调器适配器的活动方法:m_activity.updateSpinner(ftpTeacher );

            【讨论】:

              猜你喜欢
              • 2015-08-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-11-14
              • 1970-01-01
              • 2021-06-25
              • 2015-01-19
              • 2012-11-19
              相关资源
              最近更新 更多