getLoaderManager().initLoader() doesn't accept 'this' as argument though the class (ListFragment) implements LoaderManager.LoaderCallbacks<Cursor>
Asked Answered
C

19

66

I'm having trouble following a guide on using SQLite in Android. I'm using a ListFragment instead of a ListActivity(as in the example), so I have the ListFragment implement LoaderManager.LoaderCallbacks<Cursor> instead. Then, in the fillData() method in the ListFragment:

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);
}

I get the error:

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

on the marked line even though this implements LoaderManager.LoaderCallbacks<Cursor>.

Thank you for any ideas.

Crippling answered 22/6, 2012 at 12:0 Comment(1)
pastebin.com/284e26tT filldata() is at the end of the file. I changed the package name. I also probably should have mentioned that I'm using ActionBarSherlock.Crippling
S
84

You are not using the right implementations of CursorLoader and Loader. Remove your old imports and use these ones:

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

But I have the same Problem using SherlockActionBar: As I have to extend SherlockListActivity there is NO method getSupportLoadManager().

Any ideas on this?

EDIT: follow this tutorial if you do not know how to use fragments. Create a new Class with extends SherlockFragment and move your display logic there. Make your old activity extend SherlockFragmentActivity and show the newly created SherlockFragment. This way I got it working. Thanks to @JakeWharton!

Spherics answered 11/7, 2012 at 18:47 Comment(7)
SherlockListActivity extends ListActivity. Support fragments and loaders are part of the support library which means you need to extend FragmentActivity (or SherlockFragmentActivity).Maggie
Totally forgot I had an open question here, but this was the problem! Thanks!Crippling
@tasomaniac No. ListActivity provides only one or two helpers around using ListView. You can use a normal SherlockFragmentActivity and just create a ListView yourself.Maggie
@JakeWharton I am doing it but you know SherlockListFragment has beautiful progressBar when the list is loading and an automatic emptyview when the adapter is empty. Additionally progressBar hiding is animated. When I use just SherlockFragmentActivity I am missing those.Pillar
setContentView(android.R.layout.list_content) and you magically have the same thing!Maggie
@JakeWharton since which version does the list_content layout exist? Or is this the default ListActivity Layout? When I add it to my ListActivity it gives me an error, list_content cannot be resolved. Target version 16, min version 8.Spherics
@JakeWharton i have created ListView myself as you have suggested above, but now i am missing feature of android:id/empty. How to solve that? THANKS.Jimjimdandy
T
59

A few things to watch out for (from my recent experience battling with this):

  1. If your minSDK is set to less than 11 (i.e. level 10 for Gingerbread) and you are using the Support Pack for backward compatibility, make sure you use

    getSupportLoaderManager().initLoader(LOADER_ID, null, this);
    
  2. You mentioned this when you said you are using ListFragment, but it bears repeating: Do not extend Activity, otherwise the support package will not work. Instead, extend the FragmentActivity class or the ListFragment class.

  3. For your imports, make sure you are using the correct versions if your minSDK < 11:

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

Hope this helps you... or at least someone else...

Temperance answered 6/7, 2012 at 2:17 Comment(2)
I added the support v4 library but unfortunately i still dont get the getSupprtLoaderManager, i had to add actionbarsherlock library and extend the SherlockFragmentActivityNorthcliffe
is i am extending class with ACTVITY THEN will it be wrong becoz i am also having same problem when Initiating loaderHautrhin
C
10

Casting the third argument solved the problem in my case:

from

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

to

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

Note:

  1. minSdk was 8 and i was using support library v4.
  2. (android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>) this) did not work.
  3. getSupportLoaderManager() or getSupportLoadManager() did not work.
  4. This code was inside activity not fragment
Ce answered 18/6, 2014 at 6:21 Comment(6)
This throws a RuntimeException for me and I don't see how it could ever work unless it just never gets executed.Tessie
@chowey, what made you conclude that the Exception was from this piece of code? Many developers including me successfully executed it. Have you checked the lib & sdk version etc, also?Ce
I ran the code, and it crashed, and the stacktrace came back to this line of code.Tessie
And it worked for me :) Have you checked other details too as I'd mentioned in the comment? Its fine that the stacktrace came back to this line of code. But what did it say? Could you share that too?Ce
My minSdk is 27 and if I do this, I get error: "cannot be cast to android.app.LoaderManager$LoaderCallbacks"Marbling
in my case minSDK used was 8. yours is 27. not sure, but things might have changed in between.Ce
T
4

It's late but maybe help some one.
if you use loader maneger in fragment and you min api is below HONEYCOMB
you shuld use this imports

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;

and for initiate loader use this code

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

hope this help some one.

Tenotomy answered 20/6, 2016 at 11:47 Comment(0)
B
3

Change your imports to

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

and use

getSupportLoaderManager().initLoader(0, null, this);
Brownnose answered 12/2, 2016 at 14:51 Comment(0)
D
3

This is what you have:

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

This is what you should have:

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

Reason for the first one not working:

/**
 * @deprecated Use
 * {@link LoaderManager#getInstance(LifecycleOwner) LoaderManager.getInstance(this)}.
 */
Devisee answered 12/4, 2020 at 9:43 Comment(0)
T
2

My error was beacause this:

//import android.app.ListFragment; Error when doesnt import from support.v4
import android.support.v4.app.ListFragment;
Tver answered 1/10, 2014 at 13:47 Comment(0)
G
2

In my case I had to have my Activity extend ActionBarActivity from the android.support.v7.app package. I was then able to use

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

Goodale answered 24/6, 2015 at 22:28 Comment(0)
S
1

I'm using ActionBarSherlock with my app and I as well was running into this issue and worked through all the steps discussed by others in this question. However I was continuing to have the same problem after trying all the suggested resolutions.

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

The issue was I had fallen into expecting Eclipse to tell me when I was missing something and it was telling me that but not in the way I was used to. Typically Eclipse in other cases would tell me I'm missing the overrides to make something work but it's not directly saying that here. I finally picked up on the "LoaderManager.LoaderCallbacks" being the issue and realized I had no callbacks for it thus this error was actually a very valid error. Adding the basic overrides resolved my issue and allowed me to move forward.

// 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);
}
Skinned answered 2/2, 2013 at 16:52 Comment(0)
G
1

I was having a similar issue where my AsyncTaskLoader was not returning my List, but my resolution was to change the call from .initLoader to .restartLoader.

So I actually never called .initLoader and just immediately called .restartLoader.

I had a onListItemClick listener in my fragment and every time backed out of the fragment and reloaded the onListItemClick and navigated through the app it kept crashing.

It might just be specific to my app but hopefully it helps others if they are having fragment backstack reload issues.

This was part of a file manager portion in my app so it is specific to clicking multiple onListItemClicks in the fragment you are loading.

Gillett answered 2/12, 2017 at 22:12 Comment(0)
R
0

I got around this by using a SherlockListFragment (or you could use ListFragment, I suppose), but have it contained within a Activity. I first created a generic FragmentHolderActivity class that looks like this:

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);
        }
    }

}

Then you need to create an XML file for your fragment.

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" />

And here's the code you use to start the fragment:

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

You just tell the FragmentHolderActivity to use the your_list_fragment layout, which in turn loads the YourListFragment.java

You can then use: getSherlockActivity().getSupportLoaderManager().initLoader(...) in YourListFragment.java

Not sure if this is the correct approach, but it keeps all my logic in Fragments, which is nice.

Radiator answered 21/1, 2013 at 14:38 Comment(0)
R
0

Ran into the same problem. My minSdkVersion is 14, so cannot use android.support.v4 package.

I figured it by extending LoaderCallbacks, instead of LoaderManager.LoaderCallbacks and use these packages

import android.app.LoaderManager.LoaderCallbacks;  
import android.content.CursorLoader;  
import android.database.Cursor;  
import android.widget.SimpleCursorAdapter;
Rozellarozelle answered 15/11, 2013 at 1:13 Comment(0)
V
0

If you have tried all the above methods and still facing the same error with the "this" parameter, then follow these steps :

  1. Go to settings and enable imports on the fly option.(by default it'll be enabled and you can do this by using Alt+Enter keys).

  2. Cut the whole code of the activity which had implemented
    LoaderCallback... and paste it in a text editor.

  3. Then at last copy the whole code of that activity from the text editor where you had pasted, without any import commands.( Only the code of the class/activity).

  4. You'll get lots of errors as you have imported nothing yet. Just press Alt+Enter wherever you're getting the errors and it's libraries will be imported automatically. Note : Choose android.app... library for CursorLoaders.

Valuation answered 23/4, 2017 at 19:1 Comment(0)
S
0

Try these 2 lines it will work

android.support.v4.app.LoaderManager loaderManager = getSupportLoaderManager();

loaderManager.initLoader(LOADER_ID, null,  this);
Savor answered 31/8, 2018 at 0:17 Comment(0)
M
0

I am using minSDK 27 and had this same issue, I tried to cast like @Dexter suggest, but that gave an error saying cannot be cast to android.app.LoaderManager$LoaderCallbacks, so I then tried to use different import statements and this worked. I commented out the v4 versions and this is what I have now and the app is working:

//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;

Not quite sure when/how the v4 versions were imported.

Marbling answered 27/9, 2018 at 12:22 Comment(0)
P
0

If you are using fragments then just use this code.

getActivity().getSupportLoaderManager().initLoader(1, null, YourActivity.this);
Premarital answered 2/1, 2019 at 12:36 Comment(0)
E
0

I was trying to call initLoader() inside an activity. For me this worked

changing

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

to

getLoaderManager().initLoader(LOADER_ID,null,this);
Enrique answered 5/1, 2020 at 7:21 Comment(0)
J
0

If you use API 28 or later, instead of getLoaderManager use:

getSupportLoaderManager().initLoader(id, null, this);
Johnnajohnnie answered 17/4, 2020 at 16:22 Comment(0)
K
0

If you use API 29, instead of getLoaderManager use:

getSupportLoaderManager().initLoader(id, null, this);
Kappenne answered 7/5, 2020 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.