Android onLoadFinished与onLoaderReset回调详解及实例
AndroidonLoadFinished与onLoaderReset回调详解及实例
onLoadFinished
这个方法是在前面已创建的加载器已经完成其加载过程后被调用,这个方法保证会在应用到加载器上的数据被释放之前被调用。在此方法中,你必须删除所有对旧数据的使用(因为它将很快会被删除),但是不要自己去释放它们,因为它们的加载器会做这些事情。
加载器一旦了解到应用不再使用数据时,将马上释放这些数据。例如,如果数据是一个从CursorLoader来的游标,你不应调用游标的close(),如果游标被放置在一个CursorAdapter中,你应使用swapCursor()方法,以使旧的游标不被关闭。例如:
//这个Adapter被用于显示列表的数据. SimpleCursorAdaptermAdapter; ... publicvoidonLoadFinished(Loaderloader,Cursordata){ //Swapthenewcursorin.(Theframeworkwilltakecareofclosingthe //oldcursoroncewereturn.) mAdapter.swapCursor(data); }
onLoaderReset
当一个已创建的加载器被重置从而使其数据无效时,此方法被调用。此回调使你能发现什么时候数据将被释放于是你可以释放对它的引用。
下面这个实现调用参数为null的swapCursor():
//这个Adapter被用于显示列表的数据 SimpleCursorAdaptermAdapter; ... publicvoidonLoaderReset(Loaderloader){ //此处是用于上面的onLoadFinished()的游标将被关闭时执行,我们需确保我们不再使用它 mAdapter.swapCursor(null); }
例子
作为一个例子,这里完整实现了一个Fragment显示一个包含从联系人contentprovider返回查询数据的ListView的内容的功能,它使用一个CursorLoader来管理对provider的查询。
publicstaticclassCursorLoaderListFragmentextendsListFragment implementsOnQueryTextListener,LoaderManager.LoaderCallbacks{ //这是用于显示列表数据的Adapter SimpleCursorAdaptermAdapter; //如果非null,这是当前的搜索过虑器 StringmCurFilter; @OverridepublicvoidonActivityCreated(BundlesavedInstanceState){ super.onActivityCreated(savedInstanceState); //如果列表中没有数据,就给控件一些文字去显示.在一个真正的应用 //中这应用资源中取得. setEmptyText("Nophonenumbers"); //我们在动作栏中有一个菜单项. setHasOptionsMenu(true); //创建一个空的adapter,我们将用它显示加载后的数据 mAdapter=newSimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_2,null, newString[]{Contacts.DISPLAY_NAME,Contacts.CONTACT_STATUS}, newint[]{android.R.id.text1,android.R.id.text2},0); setListAdapter(mAdapter); //准备loader.可能是重连到一个已存在的或开始一个新的 getLoaderManager().initLoader(0,null,this); } @OverridepublicvoidonCreateOptionsMenu(Menumenu,MenuInflaterinflater){ //放置一个动作栏项用于搜索. MenuItemitem=menu.add("Search"); item.setIcon(android.R.drawable.ic_menu_search); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); SearchViewsv=newSearchView(getActivity()); sv.setOnQueryTextListener(this); item.setActionView(sv); } publicbooleanonQueryTextChange(StringnewText){ //在动作栏上的搜索字串改变时被调用.更新 //搜索过滤器,并重启loader来执行一个新的查询 mCurFilter=!TextUtils.isEmpty(newText)?newText:null; getLoaderManager().restartLoader(0,null,this); returntrue; } @OverridepublicbooleanonQueryTextSubmit(Stringquery){ //我们不关心这个方法 returntrue; } @OverridepublicvoidonListItemClick(ListViewl,Viewv,intposition,longid){ //写入你想写的代码 Log.i("FragmentComplexList","Itemclicked:"+id); } //这是我们想获取的联系人中一行的数据. staticfinalString[]CONTACTS_SUMMARY_PROJECTION=newString[]{ Contacts._ID, Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS, Contacts.CONTACT_PRESENCE, Contacts.PHOTO_ID, Contacts.LOOKUP_KEY, }; publicLoader onCreateLoader(intid,Bundleargs){ //当一个新的loader需被创建时调用.本例仅有一个Loader, //所以我们不需关心ID.首先设置baseURI,URI指向的是联系人 UribaseUri; if(mCurFilter!=null){ baseUri=Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(mCurFilter)); }else{ baseUri=Contacts.CONTENT_URI; } //现在创建并返回一个CursorLoader,它将负责创建一个 //Cursor用于显示数据 Stringselect="(("+Contacts.DISPLAY_NAME+"NOTNULL)AND(" +Contacts.HAS_PHONE_NUMBER+"=1)AND(" +Contacts.DISPLAY_NAME+"!=''))"; returnnewCursorLoader(getActivity(),baseUri, CONTACTS_SUMMARY_PROJECTION,select,null, Contacts.DISPLAY_NAME+"COLLATELOCALIZEDASC"); } publicvoidonLoadFinished(Loader loader,Cursordata){ //将新的cursor换进来.(框架将在我们返回时关心一下旧cursor的关闭) mAdapter.swapCursor(data); } publicvoidonLoaderReset(Loader loader){ //在最后一个Cursor准备进入上面的onLoadFinished()之前. //Cursor要被关闭了,我们需要确保不再使用它. mAdapter.swapCursor(null); } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!