Android onLoadFinished与onLoaderReset回调详解及实例

Android onLoadFinished与onLoaderReset回调详解及实例

onLoadFinished

这个方法是在前面已创建的加载器已经完成其加载过程后被调用,这个方法保证会在应用到加载器上的数据被释放之前被调用。在此方法中,你必须删除所有对旧数据的使用(因为它将很快会被删除),但是不要自己去释放它们,因为它们的加载器会做这些事情。

加载器一旦了解到应用不再使用数据时,将马上释放这些数据。例如,如果数据是一个从CursorLoader来的游标,你不应调用游标的close(),如果游标被放置在一个CursorAdapter中,你应使用swapCursor()方法,以使旧的游标不被关闭。例如:

//这个Adapter被用于显示列表的数据.
SimpleCursorAdapter mAdapter;
... 

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
  // Swap the new cursor in. (The framework will take care of closing the
  // old cursor once we return.)
  mAdapter.swapCursor(data);
} 

onLoaderReset

当一个已创建的加载器被重置从而使其数据无效时,此方法被调用。此回调使你能发现什么时候数据将被释放于是你可以释放对它的引用。

下面这个实现调用参数为null的swapCursor():

// 这个Adapter被用于显示列表的数据
SimpleCursorAdapter mAdapter;
... 

public void onLoaderReset(Loader<Cursor> loader) {
  //此处是用于上面的onLoadFinished()的游标将被关闭时执行,我们需确保我们不再使用它
  mAdapter.swapCursor(null);
}

例子

作为一个例子,这里完整实现了一个Fragment显示一个包含从联系人contentprovider 返回查询数据的ListView的内容的功能,它使用一个CursorLoader来管理对provider的查询。

public static class CursorLoaderListFragment extends ListFragment
    implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> { 

  // 这是用于显示列表数据的Adapter
  SimpleCursorAdapter mAdapter; 

  // 如果非null,这是当前的搜索过虑器
  String mCurFilter; 

  @Override public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState); 

    // 如果列表中没有数据,就给控件一些文字去显示.在一个真正的应用
    // 中这应用资源中取得.
    setEmptyText("No phone numbers"); 

    // 我们在动作栏中有一个菜单项.
    setHasOptionsMenu(true); 

    // 创建一个空的adapter,我们将用它显示加载后的数据
    mAdapter = new SimpleCursorAdapter(getActivity(),
        android.R.layout.simple_list_item_2, null,
        new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
        new int[] { android.R.id.text1, android.R.id.text2 }, 0);
    setListAdapter(mAdapter); 

    // 准备loader.可能是重连到一个已存在的或开始一个新的
    getLoaderManager().initLoader(0, null, this);
  } 

  @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // 放置一个动作栏项用于搜索.
    MenuItem item = menu.add("Search");
    item.setIcon(android.R.drawable.ic_menu_search);
    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    SearchView sv = new SearchView(getActivity());
    sv.setOnQueryTextListener(this);
    item.setActionView(sv);
  } 

  public boolean onQueryTextChange(String newText) {
    // 在动作栏上的搜索字串改变时被调用.更新
    //搜索过滤器,并重启loader来执行一个新的查询
    mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
    getLoaderManager().restartLoader(0, null, this);
    return true;
  } 

  @Override public boolean onQueryTextSubmit(String query) {
    // 我们不关心这个方法
    return true;
  } 

  @Override public void onListItemClick(ListView l, View v, int position, long id) {
    // 写入你想写的代码
    Log.i("FragmentComplexList", "Item clicked: " + id);
  } 

  // 这是我们想获取的联系人中一行的数据.
  static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
    Contacts._ID,
    Contacts.DISPLAY_NAME,
    Contacts.CONTACT_STATUS,
    Contacts.CONTACT_PRESENCE,
    Contacts.PHOTO_ID,
    Contacts.LOOKUP_KEY,
  };
  public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // 当一个新的loader需被创建时调用.本例仅有一个Loader,
    //所以我们不需关心ID.首先设置base URI,URI指向的是联系人
    Uri baseUri;
    if (mCurFilter != null) {
      baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
          Uri.encode(mCurFilter));
    } else {
      baseUri = Contacts.CONTENT_URI;
    } 

    // 现在创建并返回一个CursorLoader,它将负责创建一个
    // Cursor用于显示数据
    String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
        + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
        + Contacts.DISPLAY_NAME + " != '' ))";
    return new CursorLoader(getActivity(), baseUri,
        CONTACTS_SUMMARY_PROJECTION, select, null,
        Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
  } 

  public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // 将新的cursor换进来.(框架将在我们返回时关心一下旧cursor的关闭)
    mAdapter.swapCursor(data);
  } 

  public void onLoaderReset(Loader<Cursor> loader) {
    //在最后一个Cursor准备进入上面的onLoadFinished()之前.
    // Cursor要被关闭了,我们需要确保不再使用它.
    mAdapter.swapCursor(null);
  }
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android onLoadFinished与onLoaderReset回调详解及实例

    Android onLoadFinished与onLoaderReset回调详解及实例 onLoadFinished 这个方法是在前面已创建的加载器已经完成其加载过程后被调用,这个方法保证会在应用到加载器上的数据被释放之前被调用.在此方法中,你必须删除所有对旧数据的使用(因为它将很快会被删除),但是不要自己去释放它们,因为它们的加载器会做这些事情. 加载器一旦了解到应用不再使用数据时,将马上释放这些数据.例如,如果数据是一个从CursorLoader来的游标,你不应调用游标的close(),如果

  • Android获取分享应用列表详解及实例

    Android获取分享应用列表详解及实例 如果在应用的AndroidManifest.xml中含有 ACTION_SEND 属性,那就证明该应用可以供第三方应用进行调用分享,那怎么获取函数该属性的分享列表了,这对我们做应用的非常有用:最近在做该功能,自己也做了下自定义的分享列表,用PopupWindow的方式弹出. 1.布局: popup_share.xml <?xml version="1.0" encoding="utf-8"?> <Linea

  • Android 列表选择框 Spinner详解及实例

    Android 列表选择框 Spinner详解及实例 Spinner 是 Android 的列表选择框,不过 spinner 并不需要显示下拉列表,而是相当于弹出一个菜单供用户选择. Spinner 属性: ● android:spinnerMode:列表显示的模式,有两个选择,为弹出列表(dialog)以及下拉列表(dropdown),如果不特别设置,为下拉列表. ● android:entries:使用<string-array.../>资源配置数据源. ● android:prompt:

  • Android LayoutInflater加载布局详解及实例代码

    Android  LayoutInflater加载布局详解 对于有一定Android开发经验的同学来说,一定使用过LayoutInflater.inflater()来加载布局文件,但并不一定去深究过它的原理,比如 1.LayoutInflater为什么可以加载layout文件? 2.加载layout文件之后,又是怎么变成供我们使用的View的? 3.我们定义View的时候,如果需要在布局中使用,则必须实现带AttributeSet参数的构造方法,这又是为什么呢? 既然在这篇文章提出来,那说明这三

  • Android 活动条ActionBar的详解及实例代码

    Android 活动条ActionBar的详解 图一 图二 图三 图四 图五 ActionBar其提供的功能总结 图一使用ActionBar显示选项菜单项 menu_mainxml代码 启用程序图标导航 如何添加Action View 图二Activity代码区 menu_mainxml代码 clockxml 图三使用ActionBar实现Tab导航 创建ActionBar实现Tab导航步骤 MainActivity代码 DummyFragmentjava代码 图四Android 30之前的Fr

  • Android Handler移除Message详解及实例代码

    Android Handler移除Message详解 问题: 1.removeMessage(what)函数是否只能移除对应what值的Message? 2.对于Delayed发送的Message,能否提前remove? 代码测试: package javine.k.testhandler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Han

  • Android ListView 滚动条的设置详解及实例代码

    Android ListView 滚动条的设置详解 1.滚动条的属性 android:scrollbarAlwaysDrawHorizontalTrack 设置是否始终显示水平滚动条.这里用ScrollView.ListView测试均没有效果. android:scrollbarAlwaysDrawVerticalTrack 设置是否始终显示垂直滚动条.这里用ScrollView.ListView测试均没有效果. android:scrollbarDefaultDelayBeforeFade 设

  • Android 欢迎全屏图片详解及实例代码

    Android 欢迎全屏图片详解 其实欢迎界面就是在主Activity之前再添加一个欢迎的Activity.在这个Activity中实现欢迎界面,和其他的Activity用法 是基本一样,只有细微的差别.     1.在Activity的onCreate方法中实现: @Override ic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /**全屏设置,隐藏窗口所有装饰**/ getW

  • Android  LayoutInflater加载布局详解及实例代码

    Android  LayoutInflater加载布局详解 对于有一定Android开发经验的同学来说,一定使用过LayoutInflater.inflater()来加载布局文件,但并不一定去深究过它的原理,比如 1.LayoutInflater为什么可以加载layout文件? 2.加载layout文件之后,又是怎么变成供我们使用的View的? 3.我们定义View的时候,如果需要在布局中使用,则必须实现带AttributeSet参数的构造方法,这又是为什么呢? 既然在这篇文章提出来,那说明这三

  • Android 动态显示和隐藏状态栏详解及实例

    Android 动态显示和隐藏状态栏 View类提供了setSystemUiVisibility和getSystemUiVisibility方法,这两个方法实现对状态栏的动态显示或隐藏的操作,以及获取状态栏当前可见性. setSystemUiVisibility(int visibility)方法可传入的实参为: 1. View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,Activity不全屏显示(恢复到有状态的正常情况). 2. View.INVISIBLE:隐藏状态栏,同时A

随机推荐