Android 获取联系人并将其保存到SQLite数据库中会长时间阻塞UI

Android 获取联系人并将其保存到SQLite数据库中会长时间阻塞UI,android,android-sqlite,android-contacts,Android,Android Sqlite,Android Contacts,我使用下面的代码获取所有联系人并保存在本地数据库中 获取联系人: ArrayList<ContactHolder> contactList = new ArrayList<ContactHolder>(); String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"; Cursor managedCursor = mContext.getContentResol

我使用下面的代码获取所有联系人并保存在本地数据库中

获取联系人:

ArrayList<ContactHolder> contactList = new ArrayList<ContactHolder>();


    String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
    Cursor managedCursor = mContext.getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
            null, order);

    int _number = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
    int _name = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int _id = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);



    while (managedCursor.moveToNext()) {

        ContactHolder holder = new ContactHolder();
        //String mData = Utility.filterLocaleWithAppropreateFlagsTest(mContext, managedCursor.getString(_number));
        holder.setNumber(managedCursor.getString(_number).replaceAll("\\s+",""));
        holder.setName(managedCursor.getString(_name));
        holder.setImageUrl(managedCursor.getString(_name));
        contactList.add(holder);
    }
 public static ArrayList<ContentValues> getContactDetails(final Context mContext){
    ArrayList<ContentValues> contactList = new ArrayList<ContentValues>();


    String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
    Cursor managedCursor = mContext.getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
            null, order);

    int _number = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
    int _name = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int _id = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);



    while (managedCursor.moveToNext()) {

        ContentValues values = new ContentValues();
        Contact mContact = new Contact();


            values.put(ContactClass.CONTACT_NAME, managedCursor.getString(_name));
            values.put(ContactClass.CONTACT_MOBILE_NUMBER, managedCursor.getString(_number).replaceAll("\\s+",""));
            mContact.setPhNo(managedCursor.getString(_number).replaceAll("\\s+",""));
            mContact.setName(managedCursor.getString(_name));

            contactList.add(values);
            serverContactList.add(mContact);

        }
    }

    return contactList;
}
ArrayList contactList=new ArrayList();
字符串顺序=ContactsContract.CommonDataTypes.Phone.DISPLAY\u NAME+“ASC”;
游标managedCursor=mContext.getContentResolver().query(
ContactsContract.CommonDataTypes.Phone.CONTENT\u URI,null,null,
零,订单);
int _number=managedCursor
.getColumnIndex(ContactsContract.CommonDataTypes.Phone.NUMBER);
int_name=managedCursor
.getColumnIndex(ContactsContract.CommonDataTypes.Phone.DISPLAY\u NAME);
int _id=managedCursor
.getColumnIndex(ContactsContract.CommonDataTypes.Phone.\u ID);
while(managedCursor.moveToNext()){
ContactHolder=新的ContactHolder();
//String mData=Utility.filterLocaleWithAppropreateFlagsTest(mContext,managedCursor.getString(_number));
holder.setNumber(managedCursor.getString(_number).replaceAll(“\\s+”,”);
holder.setName(managedCursor.getString(_name));
holder.setImageUrl(managedCursor.getString(_name));
联系人列表。添加(持有人);
}
保存在SQLite数据库中:

 public List<Contact> insertContactDetails() {

    ArrayList<ContactHolder> arr = Utility.getContactDetails(context);
    List<Contact> serverArr = new ArrayList<Contact>();
    List<ContentValues> list = new ArrayList<ContentValues>();
    for (int i = 0; i < arr.size(); i++) {
        String mLocaleNo = "";

        ContactHolder mObject = arr.get(i);
        String mData = Utility.filterLocaleWithAppropreateFlagsTest(context, mObject.getNumber().replaceAll("\\s+",""));
        if (mData != null) {
            Contact mContact = new Contact();

            ContentValues values = new ContentValues();
            values.put(CONTACT_NAME, mObject.getName());
            mContact.setName(mObject.getName());

            values.put(CONTACT_MOBILE_NUMBER, mObject.getNumber().replaceAll("\\s+",""));


            values.put(CONTACT_IMAGE, mObject.getImageUrl());
            ArrayList<String> extra = new ArrayList<String>();
            StringTokenizer token = new StringTokenizer(mData);

            while (token.hasMoreElements()) {
                extra.add(String.valueOf(token.nextElement()));
            }

            mLocaleNo = extra.get(0);
            int mLocaleFlag = Integer.parseInt(extra.get(1));

            values.put(LOCALE_NUMBER, mLocaleNo);
            mContact.setPhNo(mLocaleNo);
            values.put(LOCALE_FLAG, mLocaleFlag);
            values.put(REG_STATUS, "0");

            list.add(values);
            serverArr.add(mContact);
        }
        /*
        arr.get(i).setContactStatus("0");
        arr.get(i).setLocaleNumber(mLocaleNo);*/
    }

    ourDatabase.beginTransaction();
    for (ContentValues entry : list) {

        try{
            long id = ourDatabase.insertOrThrow(CONTACT_TABLE, null, entry);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    ourDatabase.setTransactionSuccessful();
    ourDatabase.endTransaction();

    return serverArr;

}  
公共列表insertContactDetails(){
ArrayList arr=Utility.getContactDetails(上下文);
List serverArr=new ArrayList();
列表=新的ArrayList();
对于(int i=0;i
一切都如预期的那样工作,但如果触点尺寸很大,那么实际问题就出现在画面上,使屏幕长时间保持白色


我仍然没有找到任何适当的解决办法来处理这个问题

如果数据很大,则应使用游标加载程序进行保存/检索

使用游标加载程序有三个关键好处:

  • 查询是在后台线程上为您处理的(由于是在AsyncTaskLoader上构建的),因此大数据查询不会阻塞UI。这是文档建议您在使用普通光标时执行的操作,但现在它是在后台完成的
  • 游标加载程序正在自动更新。除了执行初始查询外,CursorLoader还向您请求的数据集注册ContentObserver,并在数据集更改时对自身调用forceLoad()
  • 这将导致在数据更改时获得异步回调,以更新视图

  • 要了解更多信息,我建议只使用
    ContentValues
    作为模型来处理从源到目标的联系人

    如果你不去挖掘,你就能找出真正的问题。您正在使用contactHolder存储并再次检索内容值,我认为这是不必要的。只需按如下所示更改代码并查看改进

    我只是在一个方法中添加了您的代码,并在其中添加了一些更改

    获取联系人:

    ArrayList<ContactHolder> contactList = new ArrayList<ContactHolder>();
    
    
        String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
        Cursor managedCursor = mContext.getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
                null, order);
    
        int _number = managedCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
        int _name = managedCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
        int _id = managedCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
    
    
    
        while (managedCursor.moveToNext()) {
    
            ContactHolder holder = new ContactHolder();
            //String mData = Utility.filterLocaleWithAppropreateFlagsTest(mContext, managedCursor.getString(_number));
            holder.setNumber(managedCursor.getString(_number).replaceAll("\\s+",""));
            holder.setName(managedCursor.getString(_name));
            holder.setImageUrl(managedCursor.getString(_name));
            contactList.add(holder);
        }
    
     public static ArrayList<ContentValues> getContactDetails(final Context mContext){
        ArrayList<ContentValues> contactList = new ArrayList<ContentValues>();
    
    
        String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
        Cursor managedCursor = mContext.getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
                null, order);
    
        int _number = managedCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
        int _name = managedCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
        int _id = managedCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
    
    
    
        while (managedCursor.moveToNext()) {
    
            ContentValues values = new ContentValues();
            Contact mContact = new Contact();
    
    
                values.put(ContactClass.CONTACT_NAME, managedCursor.getString(_name));
                values.put(ContactClass.CONTACT_MOBILE_NUMBER, managedCursor.getString(_number).replaceAll("\\s+",""));
                mContact.setPhNo(managedCursor.getString(_number).replaceAll("\\s+",""));
                mContact.setName(managedCursor.getString(_name));
    
                contactList.add(values);
                serverContactList.add(mContact);
    
            }
        }
    
        return contactList;
    }
    

    如果你在后台线程中做所有这些事情,正如其他人建议的那样。

    将你的方法插入到ActucDo的ActucDO这个过程中,后台使用“代码> AycCastase<代码>。是的。但是我认为它只处理空白UI问题,而不是联系问题。我需要一个更好的解决方案来快速插入触点。让我先试试异步解决方案。嗯,你可以改进你的代码,这将使它变得更好faster@Ranjit你能解释清楚一点吗。我使用的代码与其他人在获取和插入联系人时使用的代码相同。如何从此获取电子邮件。