【问题标题】:getLoaderManager().initLoader() doesn't accept 'this' as argument though the class (ListFragment) implements LoaderManager.LoaderCallbacks<Cursor>getLoaderManager().initLoader() 不接受“this”作为参数,尽管类 (ListFragment) 实现了 LoaderManager.LoaderCallbacks<Cursor>
【发布时间】:2012-06-24 17:25:48
【问题描述】:

我在关注guide 在 Android 中使用 SQLite 时遇到问题。我使用ListFragment 而不是ListActivity(如示例中所示),所以我使用ListFragment 实现LoaderManager.LoaderCallbacks&lt;Cursor&gt;。然后,在ListFragment中的fillData()方法中:

private void fillData() {
    // Fields from the database (projection)
    // Must include the _id column for the adapter to work
    String[] from = new String[] { NotesSQLiteHelper.COLUMN_TITLE };
    // Fields on the UI to which we map
    int[] to = new int[] { R.id.label };

    getLoaderManager().initLoader(0, null, this); //error
    adapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.notes_row, null, from, to, 0);
    setListAdapter(adapter);
}

我得到错误:

The method initLoader(int, Bundle, LoaderManager.LoaderCallbacks<D>) in the type LoaderManager is not applicable for the arguments (int, null, NotesActivity.ArrayListFragment)

在标记线上,即使 this 实现了 LoaderManager.LoaderCallbacks&lt;Cursor&gt;

感谢您的任何想法。

【问题讨论】:

  • pastebin.com/284e26tT filldata() 在文件末尾。我更改了包名。我也可能应该提到我正在使用 ActionBarSherlock。

标签: android sqlite android-loadermanager android-listfragment


【解决方案1】:

您没有使用正确的CursorLoaderLoader 实现。 删除旧的导入并使用这些:

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;

但是我在使用 SherlockActionBar 时遇到了同样的问题: 因为我必须扩展SherlockListActivity,所以没有方法getSupportLoadManager()

对此有什么想法吗?

编辑:如果您不知道如何使用片段,请关注this tutorial。使用 extends SherlockFragment 创建一个新类并将您的显示逻辑移到那里。让您的旧活动扩展 SherlockFragmentActivity 并显示新创建的 SherlockFragment。这样我就让它工作了。感谢@JakeWharton!

【讨论】:

  • SherlockListActivity 扩展 ListActivity。支持片段和加载器是支持库的一部分,这意味着您需要扩展 FragmentActivity(或 SherlockFragmentActivity)。
  • 完全忘记了我在这里有一个悬而未决的问题,但这就是问题所在!谢谢!
  • @tasomaniac No. ListActivity 仅提供一两个使用 ListView 的助手。您可以使用普通的SherlockFragmentActivity,然后自己创建一个ListView
  • setContentView(android.R.layout.list_content) 你神奇地拥有同样的东西!
  • @JakeWharton 从哪个版本开始 list_content 布局存在?或者这是默认的 ListActivity 布局?当我将它添加到我的 ListActivity 时,它给了我一个错误,list_content 无法解决。目标版本 16,最低版本 8。
【解决方案2】:

需要注意的几点(根据我最近与此作斗争的经验):

  1. 如果您的 minSDK 设置为小于 11(即 Gingerbread 的级别为 10)并且您正在使用支持包以实现向后兼容性,请确保使用

    getSupportLoaderManager().initLoader(LOADER_ID, null, this);
    
  2. 你在说你使用 ListFragment 的时候提到了这个,但需要重复一下:不要扩展 Activity,否则支持包将不起作用。而是扩展 FragmentActivity 类或 ListFragment 类。

  3. 对于您的导入,如果您的 minSDK ,请确保您使用的是正确的版本

     android.support.v4.app.FragmentActivity;
     android.support.v4.app.LoaderManager;
     android.support.v4.content.Loader;
    

希望这能帮助你……或者至少是其他人……

【讨论】:

  • 我添加了支持 v4 库但不幸的是我仍然没有得到 getSupprtLoaderManager,我不得不添加 actionbarsherlock 库并扩展 SherlockFragmentActivity
  • 我是在用 ACTVITY 扩展类,那么它会不会是错误的,因为我在启动加载器时也遇到了同样的问题
【解决方案3】:

投射第三个参数解决了我的问题:

来自

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

 getLoaderManager().initLoader(0, null, (android.app.LoaderManager.LoaderCallbacks<Cursor>) this);

注意:

  1. minSdk 为 8,我使用的是支持库 v4。
  2. (android.support.v4.app.LoaderManager.LoaderCallbacks&lt;Cursor&gt;) this) 没用。
  3. getSupportLoaderManager() or getSupportLoadManager() 没用。
  4. 此代码在活动内部而不是片段

【讨论】:

  • 这会为我抛出一个 RuntimeException,除非它永远不会被执行,否则我看不出它是如何工作的。
  • @chowey,是什么让你断定异常来自这段代码?包括我在内的许多开发人员都成功地执行了它。您是否也检查了 lib 和 sdk 版本等?
  • 我跑了代码,结果崩溃了,stacktrace又回到了这行代码。
  • 它对我有用 :) 你是否也检查了我在评论中提到的其他细节?堆栈跟踪回到这行代码很好。但它说了什么?你也可以分享一下吗?
  • 我的 minSdk 是 27,如果我这样做,我会得到错误:“cannot be cast to android.app.LoaderManager$LoaderCallbacks”
【解决方案4】:

已经很晚了,但也许可以帮助一些人。
如果您在片段中使用加载程序管理器并且您的 min api 低于 HONEYCOMB
你应该使用这个导入

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;      
import android.support.v4.app.Fragment;

对于启动加载器,请使用此代码

getActivity().getSupportLoaderManager().initLoader(/loader stuff*/);

希望这对某人有所帮助。

【讨论】:

    【解决方案5】:

    将您的导入更改为

    import android.support.v4.app.Fragment;
    import android.support.v4.app.LoaderManager;
    import android.support.v4.content.Loader;
    

    并使用

    getSupportLoaderManager().initLoader(0, null, this);
    

    【讨论】:

      【解决方案6】:

      这就是你所拥有的:

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

      这是你应该拥有的:

      LoaderManager.getInstance(this).initLoader(0, null, this);
      

      第一个不工作的原因:

      /**
       * @deprecated Use
       * {@link LoaderManager#getInstance(LifecycleOwner) LoaderManager.getInstance(this)}.
       */
      

      【讨论】:

        【解决方案7】:

        我的错误是因为:

        //import android.app.ListFragment; Error when doesnt import from support.v4
        import android.support.v4.app.ListFragment;
        

        【讨论】:

          【解决方案8】:

          就我而言,我必须让我的 Activity 从 android.support.v7.app 包中扩展 ActionBarActivity。然后我就可以使用

          getSupportLoaderManager().initLoader(0, null, this);

          【讨论】:

            【解决方案9】:

            我在我的应用程序中使用 ActionBarSherlock,我也遇到了这个问题,并完成了其他人在这个问题中讨论的所有步骤。但是,在尝试了所有建议的解决方案后,我仍然遇到同样的问题。

            The method initLoader(int, Bundle, LoaderManager.LoaderCallbacks<D>) in the type LoaderManager is not applicable for the arguments (int, null, this)
            

            问题是我一直期待 Eclipse 会在我丢失某些东西时告诉我,它会告诉我,但不是以我习惯的方式。通常 Eclipse 在其他情况下会告诉我我错过了使某些工作正常工作的覆盖,但这并不是在这里直接说的。我终于发现“LoaderManager.LoaderCallbacks”是问题所在,并意识到我没有回调它,因此这个错误实际上是一个非常有效的错误。添加基本​​覆盖解决了我的问题并允许我继续前进。

            // Creates a new loader after the initLoader () call
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
              // do work
              return null;
            }
            
            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
              adapter.swapCursor(data);
            }
            
            @Override
            public void onLoaderReset(Loader<Cursor> loader) {
              // data is not available anymore, delete reference
              adapter.swapCursor(null);
            }
            

            【讨论】:

              【解决方案10】:

              我遇到了类似的问题,我的 AsyncTaskLoader 没有返回我的列表,但我的解决方案是将调用从 .initLoader 更改为 .restartLoader。

              所以我实际上从未调用过 .initLoader,只是立即调用了 .restartLoader。

              我的片段中有一个 onListItemClick 侦听器,每次都退出片段并重新加载 onListItemClick 并浏览它一直崩溃的应用程序。

              它可能只是针对我的应用程序,但如果其他人遇到片段回栈重新加载问题,希望对他们有所帮助。

              这是我的应用程序中文件管理器部分的一部分,因此它特定于单击您正在加载的片段中的多个 onListItemClicks。

              【讨论】:

                【解决方案11】:

                我通过使用 SherlockListFragment(或者您可以使用 ListFragment,我想)解决了这个问题,但将其包含在 Activity 中。我首先创建了一个通用的 FragmentHolderActivity 类,如下所示:

                FragmentHolderActivity.java

                public class FragmentHolderActivity extends SherlockFragmentActivity {
                
                    public static final String FRAGMENT_LAYOUT_RESOURCE_ID = "fragment_layout_resource_id";
                
                    @Override
                    protected void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
                
                        Integer fragmentLayoutResourceId = getIntent().getIntExtra(FRAGMENT_LAYOUT_RESOURCE_ID, Integer.MAX_VALUE);
                        Assert.assertNotSame(fragmentLayoutResourceId, Integer.MAX_VALUE);
                
                        setContentView(fragmentLayoutResourceId);
                    }
                
                    @Override
                    public boolean onOptionsItemSelected(MenuItem item) {
                        switch (item.getItemId()) {
                            case android.R.id.home:
                                finish();
                                return false;
                            default:
                                return super.onOptionsItemSelected(item);
                        }
                    }
                
                }
                

                然后你需要为你的片段创建一个 XML 文件。

                your_list_fragment.xml

                <?xml version="1.0" encoding="utf-8"?>
                <fragment
                    xmlns:android="http://schemas.android.com/apk/res/android"
                    android:name="com.example.YourListFragment"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/fragment" />
                

                这是您用来启动片段的代码:

                    Intent intent = new Intent();
                    intent.setClass(this, FragmentHolderActivity.class);
                    intent.putExtra(FragmentHolderActivity.FRAGMENT_LAYOUT_RESOURCE_ID, R.layout.your_list_fragment);
                    startActivity(intent);
                

                您只需告诉 FragmentHolderActivity 使用 your_list_fragment 布局,然后加载 YourListFragment.java

                然后您可以在 YourListFragment.java 中使用:getSherlockActivity().getSupportLoaderManager().initLoader(...)

                不确定这是否是 正确 方法,但它将我所有的逻辑都保存在 Fragments 中,这很好。

                【讨论】:

                  【解决方案12】:

                  遇到了同样的问题。我的 minSdkVersion 是 14,所以不能使用 android.support.v4 包。

                  我通过扩展 LoaderCallbacks 而不是 LoaderManager.LoaderCallbacks 并使用这些包来解决这个问题

                  import android.app.LoaderManager.LoaderCallbacks;  
                  import android.content.CursorLoader;  
                  import android.database.Cursor;  
                  import android.widget.SimpleCursorAdapter;
                  

                  【讨论】:

                    【解决方案13】:

                    如果您已经尝试了上述所有方法,但使用“this”参数仍然遇到相同的错误,请按照以下步骤操作:

                    1. 转到设置并启用即时导入选项。(默认情况下它会 启用,您可以使用 Alt+Enter 键执行此操作)。

                    2. 剪切已实现的活动的整个代码
                      LoaderCallback... 并将其粘贴到文本编辑器中。

                    3. 然后最后从文本编辑器复制该活动的整个代码 您粘贴的位置,没有任何导入命令。(只有代码 课程/活动)。

                    4. 您会收到很多错误,因为您还没有导入任何内容。 只需在出现错误的地方按 Alt+Enter 即可 库将自动导入。 注意:为 CursorLoaders 选择 android.app... 库。

                    【讨论】:

                      【解决方案14】:

                      试试这两行就行了

                      android.support.v4.app.LoaderManager loaderManager = getSupportLoaderManager();
                      
                      loaderManager.initLoader(LOADER_ID, null,  this);
                      

                      【讨论】:

                        【解决方案15】:

                        我正在使用 minSDK 27 并且遇到了同样的问题,我尝试像 @Dexter 建议的那样进行投射,但是给出了一个错误,说 cannot be cast to android.app.LoaderManager$LoaderCallbacks,所以我然后尝试使用不同的导入语句并且这有效。我注释掉了v4 版本,这就是我现在拥有的,并且该应用程序正在运行:

                        //import android.support.v4.app.LoaderManager;
                        import android.app.LoaderManager;
                        import android.support.v4.app.NavUtils;
                        //import android.support.v4.content.CursorLoader;
                        import android.content.CursorLoader;
                        //import android.support.v4.content.Loader;
                        //import android.content.Loader;
                        

                        不太确定v4 版本是何时/如何导入的。

                        【讨论】:

                          【解决方案16】:

                          0

                          经过长时间的牺牲,如果您使用片段,我得到了这个解决方案,那么只需使用这段代码。

                          getActivity().getSupportLoaderManager().initLoader(1, null, YourActivity.this);

                          希望对你有帮助

                          【讨论】:

                            【解决方案17】:

                            我试图在活动中调用initLoader()。对我来说这很有效

                            变化

                            getSupportLoaderManager().initLoader(LOADER_ID,null,this);
                            

                            getLoaderManager().initLoader(LOADER_ID,null,this);
                            

                            【讨论】:

                              【解决方案18】:

                              如果您使用 API 28 或更高版本,请使用:而不是 getLoaderManager

                              getSupportLoaderManager().initLoader(id, null, this);
                              

                              【讨论】:

                                【解决方案19】:

                                如果您使用 API 29,而不是 getLoaderManager 使用:

                                getSupportLoaderManager().initLoader(id, null, this);
                                

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2012-01-12
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2018-02-08
                                  相关资源
                                  最近更新 更多