0

I have 1000 lines in a file which will be served to the user every time he/she loads the application.

My current approach is:

MainActivity: onCreate: Start an AsyncTask

AsyncTask onPreExecute: show progress dialiog

AsyncTask doInBackground: Check if the key/value is present in sharedpreferences, If yes, then do nothing in doInBackground. If no (first time user), read from the raw file and create a stringbuilder. Store the content of StringBuilder as key value pair in sharedpreferences.

AsyncTask onPostExecute: populate textview from sharedpreferences. Dismiss the progress dialog.

The code to read from file in the doInBackground method is:

StringBuilder sb = new StringBuilder();
InputStream textStream = getBaseContext().getResources().openRawResource(R.raw.file);
BufferedReader bReader = new BufferedReader(new InputStreamReader(textStream));

String aJsonLine = null;
try {
    while ((aJsonLine = bReader.readLine()) != null) {
        sb.append(aJsonLine + System.getProperty("line.separator"));
    }
} catch (IOException e) {
    e.printStackTrace();
} finally{
    try {
        bReader.close();
        textStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

I am seeing that the user has to wait for around 9-10 seconds for first launch and 4-5 seconds for subsequent launches. Any suggestions to improve the performance in my case.

4
  • 1000 lines is fast, not need Async task Commented Mar 25, 2013 at 5:52
  • Depends on the network speed also. You can use service if you want the user to interact with the ui. You can use robospice. Commented Mar 25, 2013 at 5:53
  • @matheszabi, The UI hangs for 10 seconds if I don't use Async Task. Commented Mar 25, 2013 at 5:54
  • @Sandeep I didn't pay attention for networking, I tough it is from internal memory. In this case I am stating the AsyncTask at onPostCreate or something onPost at Activity creation. The string loading it is at non ui thread: doInBackground and at onPostExecute it is dismissed the loading dialog Commented Mar 25, 2013 at 6:59

3 Answers 3

1

You don't need to make your user to wait for the whole list to get loaded. Once you have enough data to fill the screen (10-20 items, maybe?), populate the onscreen list or whatever with the data you already have, this will make the delay totally insignificant.

You may check http://developer.android.com/reference/android/content/AsyncTaskLoader.html to see how it's supposed to be done.

Sign up to request clarification or add additional context in comments.

2 Comments

your suggestions looks promising to reduce the overhead of fetching 1000 lines of text and then showing 1000 lines in textview in one go. But I have doubt that how do I control the lines to displayed on different screen densities. For example if I want to make sure that out of 1000, only 10 lines be displayed on launch, how can I ensure it for all screen densities? Any ideas would completely resolve my problem.
when you use AsyncTaskLoader, the loader will inform your Activity that there's new data available,it might be 5 items, maybe 10, you just take them and refresh your view. then more items come. finally the screen is full and it's possible to scroll up and down. all this while the rest is still loading, and your user does not have to watch progress bar, (s)he can start working with items on the screen immediately, maybe selecting one and jumping to another Activity, interrupting the loading of the rest of the data.
1

As a small sideline to the other comments, as aJsonLine is a String, it's a better idea to store its value along with the newline by using two append() instead of a single one:

sb.append(aJsonLine);
sb.append(System.getProperty("line.separator"));

instead of:

sb.append(aJsonLine + System.getProperty("line.separator"));

With the later, both the aJsonLine and the result of System.getProperty("line.separator")) need to be converted to StringBuilder before the concatenation between them with can take place and the final value be passed as a parameter.

Of course, you should also cache the value of System.getProperty("line.separator")) al

1 Comment

thanks. though I had cached the value of line.separator after posting this question, your point about using separate append statement is good.
0

I'd rather read the JSON stream through a JsonReader and extract the name value pairs I'm interested in. String concatenation / garbage collection are expensive operations. The way the code is written now, these operations will slow down the task. Also there are inefficiencies in the code like accessing the line separator on every iteration of the loop System.getProperty("line.separator").

You should see a significant performance boost just by using a JSONReader.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.