2

I have a news app where I fetch a couple of XMLs and APIs and insert into database at once. I'm using AsyncTask during the fetching/inserting into Database process. However I still get a block(UI Doesn't not respond)

for (int i = 0; i < urls.size(); i++) {
    MyAsyncTask myAsyncTask =  new MyAsyncTask(urls.get(i));
    myAsyncTask.execute();
}

The AsyncTask class:

  private class MyAsyncTask extends AsyncTask<Void,Void,Void> {

    Url mUrl;
    public MyAsyncTask(Url url){
        this.mUrl = url;
    }


    @Override
    protected Void doInBackground(Void... params) {
        connect(mUrl.getUrl(),mUrl.getSourceName(),mUrl.getChoice(),mUrl.getId());
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        whenToInflate[mUrl.getId()] = true;
        mProgressState += 15;
        mProgress.setProgress(mProgressState);

        if (areAllTrue(whenToInflate)) {
            inflate(1907);
            Arrays.fill(whenToInflate, false);
        }
    }
}

The connect method:

private void connect(String url, final String sourceSite, final int sourceChoice, final int i) {


    stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    try {
                        if (sourceChoice == 14) {
                            database.insertFixtures(response, "FOOTBALL");
                        } else if (sourceChoice == 10 || sourceChoice == 20) {
                            database.insertNews(response, sourceChoice);
                        } else {
                            if (sourceChoice == 1) response = URLDecoder.decode(URLEncoder.encode(response, "iso8859-1"), "UTF-8");
                            database.insertNewsXML(response, sourceSite, sourceChoice);
                        }


                    } catch (IllegalStateException | IllegalArgumentException | UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }

                }
            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();

        }
    });

    VolleySingleton.getInstance(getActivity()).addToRequestQueue(stringRequest);
}

The VolleySingleton class:

public class VolleySingleton {
    private static VolleySingleton instance;
    private static VolleySingleton ourInstance = new VolleySingleton();
    private RequestQueue requestQueue;

    private VolleySingleton() {
    }

    private VolleySingleton(Context context) {
        requestQueue = Volley.newRequestQueue(context);
    }

    public static VolleySingleton getInstance() {
        return ourInstance;
    }

    public static VolleySingleton getInstance(Context context) {
        if (instance == null) {
            instance = new VolleySingleton(context);
        }
        return instance;
    }

    public RequestQueue getRequestQueue() {
        return requestQueue;
    }


    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag("App");
        getRequestQueue().add(req);
    }
}
George2456
  • 340
  • 5
  • 19

2 Answers2

1

Thats because you are updating the progress of mProgress. so thats why it is giving error. Update the progress in onProgressUpdate method AsyncTask.

Hardik Chauhan
  • 2,750
  • 15
  • 30
  • Check my update, I fixed and still the UI is getting blocked, doesn't seem to be the issue – George2456 Oct 10 '15 at 16:32
  • 1
    ok. But onPostExecute will only get called once after doInBackground. – Hardik Chauhan Oct 10 '15 at 16:34
  • Yea I know, I check if my boolean array is all true, if it is then I inflate the data as all the sites are fetched and inserted in the database – George2456 Oct 10 '15 at 16:40
  • 1
    @busted13 I suspect that Hardik is right: inflating in the postExecute makes your UI available only after the execution is done. – Nir Alfasi Oct 10 '15 at 16:53
  • So when/where should I inflate the data? I tried inside the doinbackground while it was inside the Connect Method and now its inside the OnPostExecute method and still the same result – George2456 Oct 10 '15 at 16:59
0

Looks strange that your project used Volley inside AsyncTask, I haven't ever done such a thing before.

I suggest that you read my answers at the following questions for your reference:

Android Volley: Static vs Object

POST Request Json file passing String and wait for the response Volley

In which you will find that I use an Interface as the following:

public interface VolleyResponseListener {
    void onError(String message);

    void onResponse(Object response);
}

Then I pass VolleyResponseListener as a parameter of the method, in your case that is connect method.

Back to your issue, IMO, you only need to call your Volley request in your main thread (I mean stringRequest = new StringRequest... called directly inside onCreate for example)

Hope this helps!

Community
  • 1
  • 1
BNK
  • 23,994
  • 8
  • 77
  • 87