2016-06-06 52 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(),而不是在活动中保存实例,解决了我所有的问题!现在联系人检索速度稍快,但仍然不理想。有关我如何加快速度的任何想法? –

相关问题