Loader在Android3.0引进,它让异步加载数据变得容易。
特征:
1.在Activity、Fragment中都可以使用
2.Loader可以提供异步加载数据
3.监视数据源的变化,当数据源发生变化的时候,会传递新的数据
4.当loader重建的时候,会自动链接到最后一个Loader的cursor数据上,而不去进行重新查找。
在app中使用Loader的时候,可能使用到的类和接口:
LoaderManager:这是一个抽象类,关联在Activity、Fragment上,管理一个或多个Loader,帮助app管理耗时操作在Activity、Fragment的生命周期过程中。最常和CursorLoader一块使用。每一个Activity或Fragment只有一个FragmentManager对象。一个FragmentManager可以管理多个Loader
LoaderManager.LoaderCallbacks:和LoaderManger关联在一起的回调接口。onCreateLoader()会调方法,创建Loader对象。
Loader:抽象类,异步加载数据。主要使用CursorLoader。监视数据源的变化,当数据源发生改变的时候,传递新的数据内容。
AsyncTaskLoader:抽象的,提供了一个AsyncTask
CursorLoader:是AsyncTaskLoader的子类,使用ContentResolver查找数据,返回Cursor。加载Cursor数据的时候操作在非UI线程,so,不会阻塞UI线程。该类是查找ContentProvider提供出来的数据的最好的方式。
LoaderManager:用它实例化Loader--》cursorLoader
使用Loader:
1.Activity、Fragment
2.LoaderManager的实例
3.CursorLoader在后台加载数据--》ContentProvider
4.LoaderManager.LoaderCallbacks实现
5.需要展示数据的:SimpleCursorAdapter
6.数据源:ContentProvider
在一个Activity、Fragment中,只有一个LoaderManager实例。
需要在Activity的onCraete方法中或者是Fragment的onActivityCreated方法中实例化Loader对象:
getLoaderManager().initLoader(0,null, this);
public class MainActivity extends Activity implements LoaderCallbacks<Cursor>,OnQueryTextListener{ private TextView tv; private ListView lv; private SimpleCursorAdapter cursorAdapter; private String filterName=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv=(TextView) findViewById(R.id.tv); tv.setText("请稍候"); cursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_2, null, new String[]{ContactsContract.Contacts.DISPLAY_NAME}, new int[]{android.R.id.text1},0); lv=(ListView) findViewById(R.id.lv); lv.setAdapter(cursorAdapter); //初始化Loader //参数1:实例化Loader数据加载的id //参数2:传递参数onCreateLader()方法的第二个参数 //参数3:回调接口 getLoaderManager().initLoader(0, null, this); } @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 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=Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(filterName)); } //创建Loader对象,开始异步加载数据 return new CursorLoader(this, uri, pro, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { //得到异步加载数据,更新Adapter //交换Cursor,就是把之前已经有的Cursor交换掉,用data,所以起到一个更新的作用 cursorAdapter.swapCursor(data); } @Override public void onLoaderReset(Loader<Cursor> loader) { //移除adapter使用的Loader,系统会释放不再使用的Loader cursorAdapter.swapCursor(null); } @Override public boolean onQueryTextSubmit(String query) { return true; } @Override public boolean onQueryTextChange(String newText) { filterName = newText; getLoaderManager().restartLoader(0, null, this); return false; } }menu_main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity" > <item android:id="@+id/menu_search" android:actionViewClass="android.widget.SearchView" android:showAsAction="ifRoom|collapseActionView" android:title="搜索" tools:ignore="AppCompatResource"> </item> </menu>