Question

I am working on an Android app which will need to parse a fair amount of XML and/or JSON.

Every file takes 3-4 seconds to parse and this is done in a AsyncTask. The parsed data is then inserted into my SQlite database.

My problem is that the UI gets very slow and unresponsive during the parsing.

I have verified, using DDMS that almost all of the CPU is spend parsing and this happens in another (AsyncTask) thread.

I'm primarily testing on a galaxy nexus which is slow but has two cores. I therefore do not understand why I am experiencing this UI slowdown. I can still feel the slowdown on my Nexus 7 2013 but it is much less of an issue

Do you have any idea how of I could progress to fix find the cause of this issue? Shouldn't it be possible to have a heavy load on a AsyncTask without getting a laggy UI when having two cores available?

Code example

The first piece below initiates Volley and requests a number of XML files.

public static void start_update(final Context context,
        Subscription subscription) {
    if (updateConnectStatus(context) == NO_CONNECT)
        return;

    mContext = context;

    RequestManager.initIfNeeded(context);
    RequestQueue requestQueue = RequestManager.getRequestQueue();

    Cursor subscriptionCursor = Subscription.allAsCursor(context
            .getContentResolver());

    while (subscriptionCursor.moveToNext()) {

        Subscription sub = Subscription.getByCursor(subscriptionCursor);

        if (subscription == null || sub.equals(subscription)) {

            StringRequest jr = new StringRequest(sub.getUrl(),
                    new MyStringResponseListener(context
                            .getContentResolver(), sub),
                    createGetFailureListener());

            int MY_SOCKET_TIMEOUT_MS = 300000;
            DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(
                    MY_SOCKET_TIMEOUT_MS,
                    DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                    DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            jr.setRetryPolicy(retryPolicy);

            // Add the request to Volley
            requestQueue.add(jr);
            processCounts.incrementAndGet();

        }
    }
    requestQueue.start();
}

When Volley has fetced an XML file the following callback is called:

static class MyStringResponseListener implements Listener<String> {

    static FeedHandler feedHandler = new FeedHandler();
    Subscription subscription;
    ContentResolver contentResolver;
    final JSONFeedParserWrapper feedParser = null;

    public MyStringResponseListener(ContentResolver contentResolver,
            Subscription subscription) {
        this.subscription = subscription;
        this.contentResolver = contentResolver;
    }

    @Override
    public void onResponse(String response) {


        new ParseFeedTask().execute(response); // Execute the parsing as a AsyncTask
    }

    private class ParseFeedTask extends AsyncTask<String, Void, Void> {
        protected Void doInBackground(String... responses) {

            Subscription sub = null;
            String response = responses[0];
            try {
                sub = feedHandler.parseFeed(contentResolver, subscription,
                        response.replace("", "")); // Remove the Byte Order Mark
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnsupportedFeedtypeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(Long result) {
            decrementProcessCount();
        }
    }


}
Was it helpful?

Solution

It is common for Android devices to have poor storage I/O performance and if the main thread needs to access the drive for whatever reason things could get sluggish. The storage is the bottleneck, not the number of cores.

Use the profiler to see exactly what methods are slow. You may find that the UI is stuck loading data from the drive. For instance, it is common to load bitmaps on the UI thread and never notice the lag under normal conditions. In this sort of situation, move all I/O operations off the UI thread as you already have with your background data processor.

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