2016-06-06 92 views
0

在我的應用程序中,我試圖在打開時保存本地存儲中的所有聯繫人。我的代碼在沒有太多聯繫人訪問時效果很好。儘管如此,當有超過100個聯繫人時,需要永久保存它們。我正在使用Realm--一個數據庫框架,將每個聯繫人轉換爲模型對象。這是一個運行在我的應用程序首次打開加載聯繫人並保存到很長時間的領域

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

    // Operations performed in the background. 
    @Override 
    protected Void doInBackground(Void... params) { 

     // Retrieving and saving users contacts 
     Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); 
     while (phones.moveToNext()) 
     { 
      String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
      String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
      Contact.createOrUpdateWithNameAndNumber(name, phoneNumber, (RoofActivity) mContext); 
     } 
     phones.close(); 

     return null; 
    } 

    // Operations performed on UI thread. 
    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 

     enterApp(); 

    } 
} 

這是我的聯繫境界對象異步任務:

public class Contact extends RealmObject { 

private String name; 

@PrimaryKey 
private String number; 

public static void createOrUpdateWithNameAndNumber(final String name, final String number, final RoofActivity activity){ 

    ((Activity)activity).runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 

      Realm realm = activity.getRealmInstance(); 
      Contact contact = realm 
        .where(Contact.class) 
        .equalTo("name", name) 
        .equalTo("number", number) 
        .findFirst(); 

      if (contact == null) { 
       contact = new Contact(); 
      } 

      realm.beginTransaction(); 

      contact.setName(name); 
      contact.setNumber(number); 

      realm.copyToRealmOrUpdate(contact); 
      realm.commitTransaction(); 
     } 
    }); 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getNumber() { 
    return number; 
} 

public void setNumber(String number) { 
    this.number = number; 
} 

}

重要的是要注意,我只是想節省是非常重要的移動號碼。有什麼方法可以優化此代碼?還是有其他方法可以更有效地檢索這些信息。 Venmo似乎完美無瑕地完成了這件事。

回答

1

您應該對所有更新使用單個寫入事務,而不是每次插入一次,並且不應將更新分派到UI線程。

Realm有一些每事務開銷,並且當您爲每個事務插入一個對象時,此開銷將大大超過實際插入該對象所花費的時間。在單個事務中插入100個對象可能比兩個僅插入一個對象的事務花費更少的時間。

將更新調度到UI線程與您想要執行的操作完全相反;你應該試圖避免在UI線程上執行寫入事務,在沒有理由的情況下不會這樣做。

+0

當我嘗試在後臺保存這些對象時,出現以下錯誤:從不正確的線程訪問域。領域對象只能在創建它們的線程上訪問。 –

+0

'RoofActivity.getRealmInstance()'返回一個緩存實例嗎?你需要在後臺任務中爲當前線程獲取一個Realm實例(然後在任務結束時調用'close()')。 –

+0

是的,你說得對。使用Realm.getDefaultInstance(),而不是在活動中保存實例,解決了我所有的問題!現在聯繫人檢索速度稍快,但仍然不理想。有關我如何加快速度的任何想法? –

相關問題