Issue
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.
Solution
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); } }
Answered By - Solaiman Hossain
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.