title: Best way to load a large amount of data in android without making the user wait
body: <p>I'm working in an application that read phone contacts and use them in my application (Call history, Favorite contacts and All contacts).</p>
  
  <p>My UI consist of tab host control and user can swap between them, as I want my data to be shared across all my activities and also to be saved in only one place.</p>
  
  <p>So I have created a singleton class called data controller, and when I open the application I show loading screen until all data loaded.</p>
  
  <p>The problem now that user is complaining because of waiting a lot of time about (1 minute) every time they open the application when he has a very large amount of contacts, so how can I optimize my code in a good way?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>This is the method that I'm using to get all contacts:</p>
  
  <pre><code>public static ArrayList&lt;ContactInfo&gt; getAllContactWithNumberAndNameAndPhoto(
              Context context, boolean starred) {
  
          ArrayList&lt;ContactInfo&gt; retList = new ArrayList&lt;ContactInfo&gt;();
  
          ContentResolver cr = context.getContentResolver();
  
          Cursor cur = null;
          if (starred == true) {
              cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                      "starred=?", new String[] { "1" }, null);
          } else {
  
              cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null,
                      null, null);
          }
          if (cur.getCount() &gt; 0) {
              while (cur.moveToNext()) {
  
                  ContactInfo item = new ContactInfo();
                  String id = cur.getString(cur
                          .getColumnIndex(ContactsContract.Contacts._ID));
                  String name = cur
                          .getString(cur
                                  .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                  Uri photo = PhoneUtils.getPhotoUriFromID(context, id);
                  String starredValue = cur.getString(cur
                          .getColumnIndex(ContactsContract.Contacts.STARRED));
                  boolean isFav = false;
                  if (starredValue.equals("1"))
                      isFav = true;
  
                  if (Integer
                          .parseInt(cur.getString(cur
                                  .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) &gt; 0) {
                      Cursor pCur = cr.query(
                              ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                              null,
                              ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                      + " = ?", new String[] { id }, null);
                      while (pCur.moveToNext()) {
  
                          String phoneNo = pCur
                                  .getString(pCur
                                          .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                          item.addPhone(removeCharactersFromPhoneNumber(phoneNo));
                      }
                      pCur.close();
  
                      if (photo != null) {
  
                          item.setPhoto(photo.toString());
                      }
  
                      item.setName(name);
                      item.setFavorite(isFav);
                      item.setRecent(false);
  
                      retList.add(item);
                  }
              }
              cur.close();
          }
  
          return retList;
      }
  </code></pre>
  
  <p>Please let me know if I can optimize this method.</p>