Reputation: 755
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
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
Reputation: 485
I've solved Your problem on a different way ...
as usual define this interface
public interface OnFetchUrlsListener {
void onUrlsFetched(ArrayList<String> arrayList);
void onUrlsError(String error);
}
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());
}
}
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