Loader是什么,有什么作用?
顾名思义就是加载器,简单来说,Loader做了2件事:
(1)在单独的线程中读取数据,不会阻塞UI线程
(2)监视数据的更新
LoaderManager是什么,有什么作用?
LoaderManager就是加载器的管理器,一个LoaderManager可以管理一个或多个Loader,一个Activity或者Fragment只能有一个LoadManager。LoaderManager管理Loader的初始化,重启和销毁操作。
使用Loader来加载手机中的音乐为例
1、主布局,就是一个ListView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d9d9d9"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:id="@+id/music_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
</RelativeLayout>
2、ListView的Item布局,主要显示歌曲名称和歌手信息
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/music_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
<TextView
android:id="@+id/music_singer"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
3、MainActivity,注释比较详细,使用比较简单
/**
* 实现LoaderCallbacks 重写三个方法
*
* @author yungfan
*
*/
@SuppressLint("NewApi")
public class MainActivity extends Activity implements LoaderCallbacks<Cursor> {
private ListView listView;
// 使用SimpleCursorAdapter来填充数据
private SimpleCursorAdapter mAdapter;
// 使用CursorLoader来获取数据
private CursorLoader loader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.music_list);
initMusic();
}
private void initMusic() {
// 这里创建Adapter时 注意不传递数据
mAdapter = new SimpleCursorAdapter(MainActivity.this, R.layout.item,
null, new String[] { MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST }, new int[] {
R.id.music_name, R.id.music_singer }, 0);
listView.setAdapter(mAdapter);
// 通过异步的方式加载数据
LoaderManager manager = getLoaderManager();
// 第一个参数为id 第二个位Bundle数据 第三个为LoaderCallbacks
manager.initLoader(0, null, this);
}
// 首先检查指定的id是否存在,如果不存在才会触发该方法,通过该方法才能创建一个loader。
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// 查询音乐数据库 获取音乐数据 并排序
loader = new CursorLoader(this,
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
return loader;
}
// 完成对Ui控件的更新,如果不再使用,将自动释放loader的数据,不需要使用close();
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
4、运行结果,手机中的音乐数据被加载到列表中显示出来,而且是按照一定的顺序(数字 —>汉字拼音对应字母升序 —> 字母升序)
注意:必须加上读SD卡的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>