Loader簡(jiǎn)介
- Loader機(jī)制在Android 3.0版本以后引入。
- Loader提供了異步加載數(shù)據(jù)的方法,能解決長(zhǎng)時(shí)間數(shù)據(jù)加載的問(wèn)題。
- 特點(diǎn):
- 適用于任何Activity和Fragment。
- 提供了異步加載數(shù)據(jù)的機(jī)制。
- 檢測(cè)數(shù)據(jù)源,當(dāng)數(shù)據(jù)源內(nèi)容改變時(shí)他們能夠傳遞新的結(jié)果。
相關(guān)API
- LoaderManager
- 管理Loader,每個(gè)Activity或Fragment對(duì)應(yīng)一個(gè)LoaderManager。
- LoaderCallbacks
- 包含和Loader相關(guān)的回調(diào)方法。
- AsyncTaskLoader
- 抽象類,提供異步加載的方法。
- Cursors Loader
- AsyncTaskLoader的子類,提供游標(biāo)數(shù)據(jù)的加載。
使用Loader加載聯(lián)系人
1.獲得LoaderManager對(duì)象。
loaderManager = getSupportLoaderManager();
2.通過(guò)LoaderManager初始化Loader。
//動(dòng)態(tài)申請(qǐng)權(quán)限
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);
}
3.實(shí)現(xiàn)LoaderCallbacks接口。

實(shí)現(xiàn)LoaderCallbacks接口
4.在onCreateLoader方法中,創(chuàng)建CursorLoader。

創(chuàng)建CursorLoader
5.在onLoadFinished方法中,獲得加載數(shù)據(jù),更新UI。

獲得加載數(shù)據(jù),更新UI
6.在onLoaderReset方法中,清除數(shù)據(jù)。

清除數(shù)據(jù)
源碼如下:
public class LoaderActivity extends AppCompatActivity {
@BindView(R.id.listView)
ListView listView;
private LoaderManager loaderManager;
private ArrayAdapter<String> arrayAdapter ;
private List<String> contactList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loader);
ButterKnife.bind(this);
arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,contactList);
listView.setAdapter(arrayAdapter);
loaderManager = getSupportLoaderManager();
//動(dòng)態(tài)申請(qǐng)權(quán)限
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);
}
}
//callBack 實(shí)現(xiàn)
private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallback = new LoaderManager.LoaderCallbacks<Cursor>() {
private final String[] Contact_PROJECTION = {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader cursorLoader =
new CursorLoader(LoaderActivity.this,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, Contact_PROJECTION,
null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
//首先要清空數(shù)據(jù)源,避免重復(fù)數(shù)據(jù)
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<Cursor> loader) {
contactList.clear();
}
};
@Override
protected void onResume() {
super.onResume();
//loaderManager.initLoader(0,null,mLoaderCallback);
}
@Override
protected void onDestroy() {
super.onDestroy();
loaderManager.destroyLoader(0);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@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);
}
}
}
}
效果圖:

效果圖