Question

i want to get Ftp folders list from server using AsyncTask and return folders names ArrayList to main class and update spinner adapter.

In main class i got spinner with adapter

//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);

An in 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?

    }

    }

So how should i replace arraylist in AsyncTask with ArrayList in main class and update spinner updater dinamicly?

Was it helpful?

Solution 2

You already made your ArrayList static, make it public as well. and use that by your class name. and populate your ArrayList in onPostExecute(); like

     protected void onPostExecute(ArrayList<String>... result) {

    if(YourClassName.directoriesTeacher.size()>0)
     {
       YourClassName.directoriesTeacher.clear();
      }

      YourClassName.directoriesTeacher.addAll(result);

     }

OTHER TIPS

-- PSEUDO CODE --

Create a custom interface as followed:

public interface IAsyncTask {

    void IAmFinished(ArrayList<Object> arrayList);

}

Add a constructor to your AsyncTask:

private IAsyncTask asyncTaskListener;

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

In your PostExecute of the AsyncTask:

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

In your Activity that starts your AsyncTask:

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

Implement the interface:

public class MyActivity implements IAsyncTask

Implement the method:

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

I assume you don't want a spinner while fetching data, but rather to fill your spinner with data from the background task? Returning data from AsyncTask commonly relies on this pattern, using interface.

1) Create an interface so that you can post back your results: (This class you can either create in separate file or just declare it in either class)

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

2) Implement the ReturnData interface in your main class:

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) In your AsyncTask class:

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) Finally, to return data:

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

In your main, where you are calling your AsyncTask, overwrite the onPostExecute method and put your adapter stuff in there. It gets called on the UI Thread, so it's save.

So where you are calling the AsyncTask, do

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();

onPostExecute methods runs in UI thread. You can assign the result in postexecute() to your arraylist in main method. Update the adapter by calling notifydatasetChanged to update your listview.

Implement a listener passing ArrayList and use this listener for returning your ArrayList.

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

}

While invoking your async task for operation execution create an instance of TaskListener as follows:

TaskListener listener = new TaskListener() {

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

Pass this listenerobject as a parameter to the async task constructor. And create a global instance of TaskListener in the async task itself. Assign the TaskListener parameter in the constructor to the global instance.

Then in the onPostExecute of the async task class:

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

    }

In your AsyncTask you could have a member (MyActivity m_activity) with the same class of your activity.

In your AsyncTask constructor, set a MyActivity parameter and record it in m_activity.

In your onPostExecute run a method of your activity that refresh your spinner adapter: m_activity.updateSpinner(ftpTeacher );

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top