Android CursorLoader and LoaderManager Error
Y

1

1

I am trying to implement a CursorLoader and LoaderManager on a min API of 10.

However, I keep getting an IllegalArgument Exception on Line 63 of AsyncTaskLoader.class (The source Code of the AsyncTaskLoader.class where the exception is happening is Below and at this link.

/* Runs on the UI thread */
@Override
protected void onPostExecute(D data) {
    if (DEBUG) Log.v(TAG, this + " onPostExecute");
    try {
        AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
    } finally {
        done.countDown();
    }
}

Below is the stack upon the error:

AsyncTaskLoader$LoadTask.onPostExecute(Object) line: 63 
AsyncTaskLoader$LoadTask(ModernAsyncTask).finish(Object) line: 461  
ModernAsyncTask.access$500(ModernAsyncTask, Object) line: 47    
ModernAsyncTask$InternalHandler.handleMessage(Message) line: 474    
ModernAsyncTask$InternalHandler(Handler).dispatchMessage(Message) line: 99  
Looper.loop() line: 137 
ActivityThread.main(String[]) line: 4424    
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
Method.invoke(Object, Object...) line: 511  
ZygoteInit$MethodAndArgsCaller.run() line: 784  
ZygoteInit.main(String[]) line: 551 
NativeStart.main(String[]) line: not available [native method]  

I tested my content provider and I validated that the query method returns a valid cursor from my Sqlite Database. Below is the source code of my activity that I am trying to implement the CursorLoader and LoaderManager:

import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.widget.ListView;

public class Screen1_MainData extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    SimpleCursorAdapter adapter;
    ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.screen1_maindata);
        initLoader();
    }

    void initLoader() {
        String[] uiBindFrom = { Useful_Info_TableMetaData.USEFUL_INFO_COLUMN_NAME };
        int[] uiBindTo = { R.id.name };
        lv = (ListView) findViewById(R.id.screen1_MainListView);
        getSupportLoaderManager().initLoader(0, null, this);

        adapter = new SimpleCursorAdapter(this, R.layout.row, null, uiBindFrom,
                uiBindTo, 0);
        lv.setAdapter(adapter);    
    }

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

    String[] projection = { Useful_Info_TableMetaData.USEFUL_INFO_COLUMN_NAME };

    return new CursorLoader(
            this, // The Activity context
            Useful_Info_TableMetaData.CONTENT_URI, projection, null, null,
            null);
}

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        adapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        adapter.swapCursor(null);
    }
}

Does anyone see something here that I am doing wrong?

Thanks.


The app seems to make it to

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    adapter.swapCursor(data);
}

and then it throws the exception there.

Below is the logcat:

08-03 23:33:20.736: E/AndroidRuntime(17256): FATAL EXCEPTION: main 
08-03 23:33:20.736: E/AndroidRuntime(17256): java.lang.IllegalArgumentException: column '_id' does not exist 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:267) 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:78) 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:344) 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.support.v4.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:326) 
Yorgo answered 3/8, 2012 at 21:48 Comment(8)
Why did you import ListFragment and what are you doing with the ListFragment if you are using one?Dylandylana
sorry that was from a previous attempt to fix it. It is currently not used. I will update my post. ThxYorgo
Why do you have the try-catch statement in onCreateLoader?Dylandylana
Could you post more of the logcat output? The output you posted isn't really relevant to the error that you are getting... on which line in your activity is an exception being thrown?Dylandylana
You still didn't post the full logcat... I don't see the line where it says the IllegalStateException was thrown. Can you post the entire thing just for the sake of clarity?Dylandylana
I don't see an IllegalArgumentException in the logcat you posted... I also don't see anything about AsyncTaskLoader etc. in the logcat either. It's also incredibly hard to read... try and copy and paste it so that each line is on its own line next time... and you should use code blocks (not quote blocks) for logcat output.Dylandylana
It is not showing up there but it is showing up on the stack trace and the app stops working. I am about to remove the logcat because there does not seem to be anything in there that is of value to help solving this.Yorgo
Post the line that mentions the IllegalArgumentException... that is what I am asking lolDylandylana
D
10

Try moving initLoader after your call to lv.setAdapter. This will ensure that onLoadFinished (and thus adapter.swapCursor(data)) will be called after the SimpleCursorAdapter has been associated with the ListView .

Also, make sure your database has a column named _id for your primary key, as the CursorAdapter won't work otherwise. _id needs to be returned as a part of the results from the CursorLoader's. Otherwise an exception will be thrown.

Dylandylana answered 3/8, 2012 at 22:51 Comment(8)
Just tried it but got the same result. I viewed the logcat and no error/warning messages were displayed just the typical verbose messages from the debugger. Any other thoughts I have been running into a wall for the last two days on this. ThxYorgo
When does it crash? Does it just crash randomly in the background or what? Maybe place some Log.v calls in your Activity so you can see what gets executed before the Exception is thrown?Dylandylana
Ok just did that. It makes it to @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { adapter.swapCursor(data); This is the line it crashes on with the IllegalArgument Exception. }Yorgo
Does your database have a column named _id?Dylandylana
prior to converting to a content provider from direct access to the Sqlite database I did not have a column _id. I was using name as my unique primary key.Yorgo
CursorAdapter doesn't work if your database doesn't have a column named _id, so that's why it doesn't work. Somewhere in your logcat there is probably a line that reads java.lang.IllegalArgumentException: column '_id' does not exist... next time post all of the relevant parts of your logcat instead of only the parts that you think are important. :)Dylandylana
That was all of the logcat from start of program to crash.Yorgo
let us continue this discussion in chatDylandylana

© 2022 - 2024 — McMap. All rights reserved.