Himanshu Singh
Himanshu Singh

Reputation: 755

Returning ArrayList from AsyncTask

I am trying to get urls of songs from a server. I want to get all urls in an arraylist which can be shown in a recycler view in next activity. URLs are correctly received when I try to see them using Toast or log. But when I try to get them as a return result of AsyncTask it shows size = 0 for the arraylist returned. I have followed the answers from this question specially by Blackbelt. But that proved to be of no use. Comments are disabled on that answer. So, here I am posting my question with the modified code. Here is the code I have written.

    interface OnFetchUrlsListener
    {
        public void onUrlsFetched(ArrayList<String> arrayList);
        public void onUrlsError(String error);
    }

     public class SplashScreen extends AppCompatActivity implements OnFetchUrlsListener{

    @Override
    public void onUrlsFetched(ArrayList<String> arrayList) {
        Toast.makeText(this, "result size : "+arrayList.size(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUrlsError(String error) {

    }

    private static RequestQueue mQueue;
    public static ArrayList<String> songsArray ;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen);
        songsArray = new ArrayList<String>();
        String uri = Uri.parse("https://dee9c999.ngrok.io/audio/data/WebsiteSourceCode/api/all_songs.php/?allsongs=allsongs").toString();
        new FetchSongs(this).execute(uri);

    }

    private class FetchSongs extends AsyncTask<String, String, ArrayList<String>> {
        private OnFetchUrlsListener mListener;
        public FetchSongs(OnFetchUrlsListener listener){
            mListener = listener;
        }

        @Override
        protected ArrayList<String> doInBackground(String... params) {
            //some heavy processing resulting in a Data String
            JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, params[0], null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            try {
                                JSONArray jsonArray = response.getJSONArray("data");

                                for (int i = 0; i < jsonArray.length(); i++) {
                                    songsArray.add(jsonArray.getString(i));
                                }

                            }
                            catch (JSONException e) {
                                e.printStackTrace();
                                Log.d("JSON Parse", String.valueOf(e));
                            }

                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                    Toast.makeText(SplashScreen.this, "Load error!!", Toast.LENGTH_SHORT).show();
                }
            });
            mQueue.add(request);
            return songsArray;
        }

        @Override
        protected void onPreExecute() {}

        @Override
        protected void onPostExecute(ArrayList<String> result) {

            if(mListener!=null)
            {
                mListener.onUrlsFetched(result);
            }
        }
    }
}

[Edit]

 private ArrayList<String> startHeavyProcessing(String uri) {
        final ArrayList<String> result = new ArrayList<String>();
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, uri, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            JSONArray jsonArray = response.getJSONArray("data");

                            for (int i = 0; i < jsonArray.length(); i++) {
                                result.add(jsonArray.getString(i));
                                Toast.makeText(SplashScreen.this, jsonArray.getString(i), Toast.LENGTH_SHORT).show();
                            }
                            songs_fetched = true;

                        }
                        catch (JSONException e) {
                            e.printStackTrace();
                            songs_fetched = false;
                            Log.d("JSON Parse", String.valueOf(e));
                        }

                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                Toast.makeText(SplashScreen.this, "Load error!!", Toast.LENGTH_SHORT).show();
            }
        });
        mQueue.add(request);
        return result;
    }

Now, when I try to print result of the function startHeavyProcessing() it is returning an arraylist of size 0 but inside the function it is getting the songs urls perfectly fine.

Upvotes: 1

Views: 93

Answers (2)

Athira
Athira

Reputation: 1213

Try this, you dont need to return arraylist if you use this, at the end of function arraylist will have all the values

ArrayList<String> result = new ArrayList<>();
        private void startHeavyProcessing(String uri) {

            JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, uri, null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            try {
                                JSONArray jsonArray = response.getJSONArray("data");

                                for (int i = 0; i < jsonArray.length(); i++) {
                                    result.add(jsonArray.getString(i));
                                }

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

                                Log.d("JSON Parse", String.valueOf(e));
                            }

                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();

                }
            });
            mQueue.add(request);
        }

Upvotes: 0

Solaiman Hossain
Solaiman Hossain

Reputation: 485

I've solved Your problem on a different way ...

  1. as usual define this interface

    public interface OnFetchUrlsListener {
        void onUrlsFetched(ArrayList<String> arrayList);
        void onUrlsError(String error);
    }
    
  2. write down a class, say, VolleyCall where volley get request will happen & result/response will be returned using listener

    public class VolleyCall {
        private String TAG = VolleyCall.class.getSimpleName();
        private String mUrl;
        private OnFetchUrlsListener mOnFetchUrlsListener;
        private ArrayList<String> mSongs;
        private RequestQueue mQueue;
    
        public VolleyCall(Context context, String url, OnFetchUrlsListener onFetchUrlsListener) {
            mSongs = new ArrayList<>();
            mUrl = url;
            mOnFetchUrlsListener = onFetchUrlsListener;
    
            mQueue = Volley.newRequestQueue(context);
        }
    
        public void parse() {
            JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, mUrl, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            Log.e(TAG, "_log : onResponse : response : " + response.toString());
                            JSONArray jsonArray = response.getJSONArray("data");
    
                            for (int i = 0; i < jsonArray.length(); i++) {
                                mSongs.add(jsonArray.getString(i));
                            }
    
                            mOnFetchUrlsListener.onUrlsFetched(mSongs);
    
                        } catch (JSONException e) {
                            Log.e(TAG, "_log : onResponse : JSONException : " + e.getMessage());
                        }
    
                    }
                }, new Response.ErrorListener() {
             @Override
             public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "_log : onErrorResponse : error : " + error.getMessage());
                mOnFetchUrlsListener.onUrlsError(error.getMessage());
            }
        });
    
        mQueue.add(request);
        Log.e(TAG, "_log : songsArray_size : " + mSongs.size());
        }
    }
    
  3. modify your main activity

    public class SplashScreen extends AppCompatActivity implements OnFetchUrlsListener {
    
        private String TAG = SplashScreen.class.getSimpleName();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            String url = "https://dee9c999.ngrok.io/audio/data/WebsiteSourceCode/api/all_songs.php/?allsongs=allsongs";
            VolleyCall call = new VolleyCall(SplashScreen.this, url, SplashScreen.this);
            call.parse();
        }
    
        @Override
        public void onUrlsFetched(ArrayList<String> arrayList) {
            Log.e(TAG, "_log : onUrlsFetched : is_arrayList_null : " + (arrayList == null));
            if (arrayList != null) {
                Log.e(TAG, "_log : onUrlsFetched : arrayList_size : " + arrayList.size());
            }
    
            String file_names = "";
            for (String s : arrayList) {
                file_names = file_names.concat(s + "\n");
            }
    
           TextView tv = findViewById(R.id.text);
           tv.setText(file_names);
        }
    
        @Override
        public void onUrlsError(String error) {
            Log.e(TAG, "_log : onUrlsError : " + error);
        }
    }
    

Upvotes: 1

Related Questions