具有多个加载器的 LoaderManager:如何获得正确的光标加载器

Posted

技术标签:

【中文标题】具有多个加载器的 LoaderManager:如何获得正确的光标加载器【英文标题】:LoaderManager with multiple loaders: how to get the right cursorloader 【发布时间】:2011-12-18 22:27:20 【问题描述】:

对我来说,如果您有多个加载器,则不清楚如何获得正确的光标。假设您定义了两个不同的加载器:

getLoaderManager().initLoader(0,null,this);
getLoaderManager().initLoader(1,null,this);

然后在 onCreateLoader() 你根据 id 做不同的事情:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) 

    if (id==0)
               CursorLoader loader = new CursorLoader(getActivity(),
            MaterialContentProvider.CONTENT_URI,null,null,null,null);
    else
               CursorLoader loader = new CursorLoader(getActivity(),
            CustomerContentProvider.CONTENT_URI,null,null,null,null);
            ;
    return loader;
 

到目前为止一切顺利。但是如何在 onLoadFinished() 中获得正确的光标,因为您没有任何 id 来识别正确的光标适配器的正确光标。

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) 


    mycursoradapter1.swapCursor(cursor);
    if(isResumed())
        setListShown(true);
    else 
        setListShownNoAnimation(true);
    




//and where to get the cursor for mycursoradapter2

或者我错了,这是在一个片段中获取两个不同光标适配器的结果的错误方法。

【问题讨论】:

这是一个非常好的问题!它问得很好,并且触及了一个相当微妙的主题。非常具体。 应该提到的是,当所有加载器的加载器返回类型不同时,您必须使用单独的处理程序类,因为由于泛型类型擦除,Java 不会允许您实现具有多个类型的接口(在这种情况下为LoaderCallbacks)。它仅适用于您的情况,因为两次结果都是Cursor @Matthias 太好了,你提到了它!我只是在考虑如何拥有 2 个具有不同返回类型的加载器。那么如果 2 个具有 2 种不同返回类型的 loader 怎么办?使用 1 个加载器执行一项任务,而使用线程执行另一项任务? @Robert 不需要使用线程。您可以使用两个Loaders。请通过这个***.com/a/20839825/2818583 【参考方案1】:

Loader 类有一个名为getId() 的方法。我希望这会返回您与加载程序关联的 id。

【讨论】:

谢谢,库尔蒂斯!凉爽的!我会尝试它,但希望它会起作用。我有同样的想法,但没有看 loader 对象。而是查看了光标对象... 它适用于 Loader.getID()!我现在已经仔细检查过了。太好了! 我正在考虑通过使用内部/匿名类来做到这一点,这样每个加载器都有自己的对象来获取回调。 @KurtisNusbaum,为什么不正确?内部类将与外部 Activity 一起被破坏,因此这不应该导致内存泄漏或任何事情。对 Activity 有强引用的静态类在语义上等价于内部类(它保持对外部类的隐式强引用。) @Jords 这在技术上是正确的。我不是在争论这个。但是,当你可以打电话给getId() 时,为什么还要这么麻烦呢?【参考方案2】:

使用Loader的getId()方法:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) 
    switch (loader.getId()) 
        case 0:
            // do some stuff here
            break;
        case 1:
            // do some other stuff here
            break;
        case 2:
            // do some more stuff here
            break;
        default:
            break;
    
    

【讨论】:

【参考方案3】:

如果您的加载器除了结果的类类型之外没有其他共同点(此处为:Cursor),您最好创建两个单独的 LoaderCallbacks 实例(仅作为 Activity/Fragment 中的两个内部类),每个人都致力于一种装载机处理,而不是试图将苹果与橙子混合在一起。

在您的情况下,数据源和结果处理似乎都不同,这需要您编写额外的样板代码来识别当前场景并将其分派到适当的代码块。

【讨论】:

我有一个问题。 Activity 实现LoaderCallbacks 并将this 传递给getLoaderManager().initLoader() 的目的是确保LoaderManager 充当ActivityLoader 通过LoaderCallbacks 之间的通信通道。 Activity 没有实现LoaderCallbacks 而是创建匿名内部类,是如何在这里创建的通信通道? 通讯渠道是LoaderCallbacks。无需将Activity 本身用作LoaderCallbacks。在需要时创建多个沟通渠道会更简单。

以上是关于具有多个加载器的 LoaderManager:如何获得正确的光标加载器的主要内容,如果未能解决你的问题,请参考以下文章

如何向具有多个加载器的 webpack 加载器添加查询?

用于在多个活动/片段中重用的全局加载器 (LoaderManager)

Loader详解

使用 LoaderManager 加载依赖查询的首选方法

Android-LoaderManager异步加载数据库数据

你可以使用服务中的 LoaderManager 吗?