使用 Async Task 读取 phone 联系人并将它们设置为 AutoCompleteTextView 的适配器

Using Async Task to read the phone contacts and set them to an adapter for AutoCompleteTextView

我已从设备读取所有 phone 联系人并将它们设置为 AutoCompleteTextView 的适配器。执行此操作的函数是:

private void storeContactsToArrayList() {
    Log.d("In ", "storeContactsToArrayList() called");

    List<Contact> contactList = new ArrayList<>();

    ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);

    if ((cur != null ? cur.getCount() : 0) > 0) {
        while (cur != null && cur.moveToNext()) {
            String id = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts.DISPLAY_NAME));

            if (cur.getInt(cur.getColumnIndex(
                    ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 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));
//                        Log.i("GOT", "Name: " + name);
//                        Log.i("GOT", "Phone Number: " + phoneNo); //working
                    //To our POJO
                    Contact contact = new Contact();
                    contact.setName(name);
                    contact.setPhoneNumber(phoneNo);

                    contactList.add(contact);

                }
                pCur.close();
            }
            ArrayAdapter<Contact> contactsArrayAdapter =
                    new ArrayAdapter<Contact>(this, android.R.layout.simple_list_item_1, contactList);

            //setting this adapter to our autocompleteTextView userInput
            userInput.setAdapter(contactsArrayAdapter);
        }
    }
    if(cur!=null){
        cur.close();
    }
}

然而,当我 运行 代码时,我意识到该函数需要相当长的时间来执行,这看起来很糟糕。 据我所知,我应该使用像 AdapterTask extends Async Task 这样的内部 class 来异步执行相同的操作,而不会阻塞我的主 UI 线程。我试过这样做,但我做不到。 请建议我是否有任何其他方法可以在不使用 AsyncTask 的情况下做同样的事情,或者如果 AsyncTask 是可行的方法,我怎样才能使用 AsyncTask 实现上述功能正在做的事情。 谢谢

为后台任务创建一个单独的 class 并与侦听器(和接口)通信。下面是示例 根据您的需要修改它

 public class FetchContacts extends AsyncTask<Void, Void, List> {
    private Context activity;
    private OnContactFetchListener listener;
    public FetchContacts(Context context, OnContactFetchListener listener) {
        activity = context;
        this.listener = listener;
    }
    @Override
    protected List doInBackground(Void... params) {
        List<Contact> contactList = new ArrayList<>();
        // get Contacts here
        return contactList;
    }

    @Override
    protected void onPostExecute(List list) {
        super.onPostExecute(list);
        if(listener!=null){
            listener.onContactFetch(list);
        }
    }

    public interface OnContactFetchListener {
        void onContactFetch(List  list);
    }
}

可以调用为.

  new FetchContacts(activity, new FetchContacts.OnContactFetchListener() {
                @Override
                public void onContactFetch(List contacts) {
                    // Here you will get the contacts
                }
            }).execute();

喜欢@ADM 的建议。创建一个单独的 class,而不是内部 class。 FetchContacts.java

public class FetchContacts extends AsyncTask<Void, Void, List> {
private Context activity;
private OnContactFetchListener listener;

public FetchContacts(Context context, OnContactFetchListener listener) {
    activity = context;
    this.listener = listener;
}

@Override
protected List doInBackground(Void... voids) {
    List<Contact> contactList = new ArrayList<>();
    // get Contacts here

    ContentResolver cr = activity.getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);

    if ((cur != null ? cur.getCount() : 0) > 0) {
        while (cur != null && cur.moveToNext()) {
            String id = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts.DISPLAY_NAME));

            if (cur.getInt(cur.getColumnIndex(
                    ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 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));
//                        Log.i("GOT", "Name: " + name);
//                        Log.i("GOT", "Phone Number: " + phoneNo); //working
                    //To our POJO
                    Contact contact = new Contact();
                    contact.setName(name);
                    contact.setPhoneNumber(phoneNo);

                    contactList.add(contact);

                }
                pCur.close();
            }
        }
    }
    if (cur != null) {
        cur.close();
    }
    return contactList;
}

@Override
protected void onPostExecute(List list) {
    super.onPostExecute(list);
    if (listener != null) {
        listener.onContactFetch(list);
    }
}

public interface OnContactFetchListener {
    void onContactFetch(List list);
}
}

并调用 class,将联系人列表设置为 ArrayAdapter,将 arrayadapter 设置为自动完成文本视图:

new FetchContacts(MainActivity.this, new FetchContacts.OnContactFetchListener() {
        @Override
        public void onContactFetch(List contacts) {
            // Here you will get the contacts
            ArrayAdapter<Contact> contactArrayAdapter = new ArrayAdapter<Contact>(MainActivity.this,
                    android.R.layout.simple_list_item_1, contacts);
            userInput.setAdapter(contactArrayAdapter); //userInput is our AutoCompleteTextView

        }
    }).execute();