在android3.0开始,新增了Loader. Loader加载数据的方式是异步的。
Loader的特点:
1.适合于activity和fragment
2.提供了异步加载数据机制
3.监控数据源,当数据源发生改变时,会传递新结果
4.自动重连到最后一个数据加载器游标,不需要重新查询数据
使用情况:对数据源监控,比如contentProvider.
CursorLoader是AsyncTaskLoader的子类,AsyncTaskLoader会提供AsynTask去操作。故不会阻塞UI线程。
实例:获取手机号码
public class MainActivity extends ListActivity implements LoaderCallbacks<Cursor> {
//ListActivity可以不写setContentView(R.layout.activity_main),因为其含有默认的布局。
//ListActivity对应布局中的ListView的 android:id="@android :id/list"
public static final int ID = 110;
SimpleCursorAdapter adapter;
String[] showContent = new String[] {
Phone.NUMBER};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null, showContent,
new int[] { android.R.id.text1});
setListAdapter(adapter);
//参数:id,Bundle对象(onCreateLoader()中第二个参数),LoaderCallbacks<D> 对象
getLoaderManager().initLoader(ID, null, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//创建Loader对象,CursorLoader对象(含有AsyncTask的功能)会自己在后台线程加载数据,最后返回一个cursor
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
//若是出现java.lang.IllegalArgumentException: column ‘_id‘ does not exist,
//则是String[] projection中没有写入 ‘_id‘。
//simplecursoradapter在显示时根据‘_id‘来显示。故不能没有‘_id‘
CursorLoader loader = new CursorLoader(this, uri, null, null,
null, null);
return loader;
}
//Loader第一次读取完数据,或者数据源发生变化时会被调用
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
//一个loadermanager可以管理多个loader,故对loader的id进行判断
switch (loader.getId()) {
case ID:
// 将查询到数据加载到listview上
adapter.swapCursor(cursor);
break;
default:
break;
}
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
adapter.swapCursor(null);//移除引用
}
}