65

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.

Alex Lockwood
  • 81,274
  • 37
  • 197
  • 245
vurp0
  • 1,025
  • 2
  • 9
  • 13
  • http://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. – vurp0 Jun 22 '12 at 12:50

19 Answers19

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!

jesterjunk
  • 2,074
  • 17
  • 17
Matthias B
  • 5,027
  • 1
  • 40
  • 46
  • 15
    `SherlockListActivity` extends `ListActivity`. Support fragments and loaders are part of the support library which means you need to extend `FragmentActivity` (or `SherlockFragmentActivity`). – Jake Wharton Jul 11 '12 at 19:18
  • Totally forgot I had an open question here, but this was the problem! Thanks! – vurp0 Jul 12 '12 at 18:56
  • @tasomaniac No. `ListActivity` provides only one or two helpers around using `ListView`. You can use a normal `SherlockFragmentActivity` and just create a `ListView` yourself. – Jake Wharton Jan 15 '13 at 23:42
  • @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. – tasomaniac Jan 16 '13 at 11:39
  • 2
    `setContentView(android.R.layout.list_content)` and you magically have the same thing! – Jake Wharton Jan 16 '13 at 21:08
  • 1
    @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. – Matthias B Jan 17 '13 at 09:35
  • @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. – Shajeel Afzal Apr 24 '13 at 16:43
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...

ban-geoengineering
  • 15,533
  • 18
  • 140
  • 225
wileyCoyote
  • 679
  • 4
  • 6
  • I added the support v4 library but unfortunately i still dont get the getSupprtLoaderManager, i had to add actionbarsherlock library and extend the SherlockFragmentActivity – Rat-a-tat-a-tat Ratatouille Oct 06 '13 at 15:59
  • is i am extending class with ACTVITY THEN will it be wrong becoz i am also having same problem when Initiating loader – Erum Jan 22 '14 at 11:12
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
Dexter
  • 2,917
  • 2
  • 37
  • 49
  • 2
    This throws a RuntimeException for me and I don't see how it could ever work unless it just never gets executed. – chowey Feb 21 '18 at 05:26
  • @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? – Dexter Feb 21 '18 at 19:18
  • I ran the code, and it crashed, and the stacktrace came back to this line of code. – chowey Feb 21 '18 at 19:22
  • 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? – Dexter Feb 22 '18 at 07:23
  • My minSdk is 27 and if I do this, I get error: "cannot be cast to android.app.LoaderManager$LoaderCallbacks" – thehme Sep 27 '18 at 12:11
  • in my case minSDK used was 8. yours is 27. not sure, but things might have changed in between. – Dexter Sep 29 '18 at 02:59
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.

max
  • 5,014
  • 11
  • 37
  • 66
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);
anandbibek
  • 1,110
  • 9
  • 18
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)}.
 */
Doilio Matsinhe
  • 1,614
  • 10
  • 23
2

My error was beacause this:

//import android.app.ListFragment; Error when doesnt import from support.v4
import android.support.v4.app.ListFragment;
Renan Franca
  • 2,885
  • 1
  • 15
  • 17
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);

Oladipo Olasemo
  • 1,890
  • 22
  • 27
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);
}
brentil
  • 91
  • 1
  • 10
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.

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.

Joony
  • 4,170
  • 2
  • 26
  • 37
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;
Dino Tw
  • 2,791
  • 4
  • 27
  • 45
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.

Saurabh Singh
  • 1,095
  • 11
  • 11
0

Try these 2 lines it will work

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

loaderManager.initLoader(LOADER_ID, null,  this);
Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
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.

thehme
  • 1,882
  • 4
  • 21
  • 32
0

0

After a long sacrifice i got this solution if you are using fragments then just use this code.

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

i hope this is helpful for you

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

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

getSupportLoaderManager().initLoader(id, null, this);
Yigal
  • 1,170
  • 9
  • 22
0

If you use API 29, instead of getLoaderManager use:

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