Android開發之Loader與LoaderManager

yungfan發表於2016-06-02

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、執行結果,手機中的音樂資料被載入到列表中顯示出來,而且是按照一定的順序(數字 —>漢字拼音對應字母升序 —> 字母升序)

music.jpg

注意:必須加上讀SD卡的許可權

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
複製程式碼

相關文章