Android 使用Loader加载联系人



 Android 的装载器(Loader)是从Android3.0之后新引入的API,主要完成单线程耗时数据异步装载功能,并在数据有更新时自动通知UI刷新,业内也叫加载器,装载机。 

 一个使用装载器的的应用会包含以下组件:

1:一个Activity或者Fragment

2:一个LoaderManage的实例

3:一个被ContentProvider所支持的数据的CursorLoader.。或者你从Loader,AsynTaskLoader实现自己的装载器来加载数据。

4:实现LoaderManager.LoaderCallBacks,管理自己的加载器。

5:显示装载器的途径,比如说ArrayAdapter

6:一个数据源,比如当是CursorLoader,它将是一个ContentProvider


这里通过两张图来展示Loader加载数据:

Loader加载原理:

Android 使用Loader加载联系人_第1张图片


Loader加载流程:

Android 使用Loader加载联系人_第2张图片

在这里,我们通过Loader读取本地联系人,首先添加读取联系人的权限:

如果手机是版本是6.0,还需要动态申请权限。全部代码如下:

public class MainActivity extends AppCompatActivity {

    private ListView list ;
    private ArrayAdapter arrayAdapter ;
    private List contactList = new ArrayList<>();
    private LoaderManager loaderManager ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list= (ListView)findViewById(R.id.contact_list);
        arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,contactList);
        list.setAdapter(arrayAdapter);
        //获取LoaderManager
        loaderManager = getSupportLoaderManager();
        //动态申请权限
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_CONTACTS},
                    0);
        } else
        {
            loaderManager.initLoader(0, null, mLoaderCallback);
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        //loaderManager.initLoader(0,null,mLoaderCallback);
    }
   //callBack 实现
    private LoaderManager.LoaderCallbacks mLoaderCallback = new LoaderManager.LoaderCallbacks() {

        private final String[] Contact_PROJECTION = {
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER};
        @Override
        public Loader onCreateLoader(int id, Bundle args) {
            CursorLoader cursorLoader =
                    new CursorLoader(MainActivity.this,
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI, Contact_PROJECTION,
                            null, null, null);
            return cursorLoader ;
        }

        @Override
        public void onLoadFinished(Loader loader, Cursor data) {

            //首先要清空数据源,避免重复数据
            contactList.clear();
            while (data.moveToNext())
            {
                String displayName = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String number = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                //分两行展示
                contactList.add(displayName+"\n"+number);
            }
            arrayAdapter.notifyDataSetChanged();
        }

        @Override
        public void onLoaderReset(Loader loader) {
            contactList.clear();
        }

    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        loaderManager.destroyLoader(0);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e("LoaderManager","====onSaveInstanceState");
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == 0)
        {
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                loaderManager.initLoader(0, null, mLoaderCallback);
            }
        }
    }
}


这样我们就能读取本地的联系人了。


你可能感兴趣的:(Loader)