Android Loader 技術的簡單實用
來源:程序員人生 發(fā)布時間:2015-01-19 08:16:17 閱讀次數:3462次
從Android3.0開始,Android SDK提供了Loader技術,使用Loader技術可以很容易進行數據的異步加載。Loader技術為我們提供的核心類有:
- LoaderManager:可以通過Activity或的Fragment的getLoaderManager()方法得到LoaderManager,用來對Loader進行管理,1個Activity或Fragment只能有1個LoaderManager。
- LoaderManager.LoaderCallbacks:用于同LoaderManager進行交互,可以在其中創(chuàng)建Loader對象。
- AsyncTaskLoader:抽象類,可以進行異步加載數據的Loader,貌似內部也是通過AsynTask實現的,可以通過繼承它構建自己的Loader,也能夠使用現有的子類,例如異步查詢數據庫可使用CursorLoader。
使用Loader1般可以經過以下步驟:
1、初始化Loader,可使用initLoader(intid, Bundle args, LoaderManager.LoaderCallbacks<D> callback);方法進行初始化。
id:標識Loader的ID,1個Activity或Fragment只能有1個LoaderManager,但可以有多個Loader,通過ID區(qū) 分。在新建Loader時,如果發(fā)現已有相同ID的Loader就會復用該Loader,而不會重新創(chuàng)建。
args:傳給新建Loader的參數。
Callback:回調接口。
2、實現LoaderManager.LoaderCallbacks中的方法,LoaderManager.LoaderCallbacks中需要實現的方法有:
- publicLoader<D> onCreateLoader(int id, Bundle args):創(chuàng)建新的Loader,id為LoaderID,如果已有相同ID的Loader就會復用該Loader,而不會重新創(chuàng)建。 args為初始化時傳遞的參數。該方法開始異步查詢,并返回1個泛型類,如果是查詢數據庫可以返回1個CursorLoader,可以返回自定義的Loader。
- public voidonLoadFinished(Loader<D> loader, D data):異步查詢結束的會調用這個方法,并返回查詢結果 data。
- public void onLoaderReset(Loader<D> loader): 當調用Loader.reset()將Loader數據清空時,但在系統(tǒng)燒毀Loader時會自動調用Loader.reset()方法,我們1般不需要手動調用,只需要在onLoaderReset方法中,將使用Loader的移除。
3、使用 restartLoader(intid, Bundle args, LoaderManager.LoaderCallbacks<D> callback)方法進行數據更新,和初始化1個,如果有相同id的Loader存在,會復用Loader,并清空原有Loader中的數據,如果沒有就新建1個。這個方法1般使用在需要更新數據時,例以下面例子中,在搜索關鍵改變時,需要調用這個方法,重新異步查詢數據。
下面1個例子使用CursorLoader查詢聯系人名字,并顯示在ListActivity中,在ActionBar上放置了1個SearchView可以根據聯系人姓名關鍵字查詢聯系人。
Activity代碼以下:
public class MainActivity extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor>, SearchView.OnQueryTextListener {
private SimpleCursorAdapter cursorAdapter;
private String filterName=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv= (TextView) findViewById(android.R.id.empty);
tv.setText("請稍后");
cursorAdapter=new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2,
null,
new String[]{ContactsContract.Contacts.DISPLAY_NAME},
new int[]{android.R.id.text1},0);
setListAdapter(cursorAdapter);
//初始化Loader
getLoaderManager().initLoader(0,null,this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri uri;
String[] pro=new String[]{ ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts._ID};
if(TextUtils.isEmpty(filterName)){
uri= ContactsContract.Contacts.CONTENT_URI;
}else{
uri=Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,Uri.encode(filterName));
}
//創(chuàng)建Loader對象,開始異步加載數據
return new CursorLoader(this,uri,pro, null, null,null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
//得到異步加載數據,更新Adapter
cursorAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
//移除adapter使用的Loader,系統(tǒng)會釋放不再使用的Loader
cursorAdapter.swapCursor(null);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main,menu);
SearchView v= (SearchView) menu.findItem(R.id.menu_search).getActionView();
v.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
filterName=newText;
//使用新的Loader(清空舊的數據)
getLoaderManager().restartLoader(0,null,this);
return false;
}
}
菜單資源文件:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:actionViewClass="android.widget.SearchView"
android:id="@+id/menu_search"
android:showAsAction="ifRoom|collapseActionView"
android:title="搜索"
tools:ignore="AppCompatResource" />
</menu>
最后來個效果圖:

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈