user1611830
user1611830

Reputation: 4867

method clash from android LoaderManager

Suppose I have an android app with a Feed class, which is called by some Fragment implemented as follows and throwing : java.lang.ClassCastException: com.newsfeeder.ui.MainFragment cannot be cast to android.app.LoaderManager$LoaderCallbacks

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

public class MainFragment extends Fragment implements   LoaderManager.LoaderCallbacks<List<Feed>>
{   
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState)
    {
        View v=inflater.inflate(R.layout.main_container, null);
        listView = (ListView) v.findViewById(R.id.list);
        getLoaderManager().initLoader(0, null, (android.app.LoaderManager.LoaderCallbacks<Object>) this);

        return v;
    } 
public Loader<List<Feed>> onCreateLoader(int id, Bundle args) {
        final List<Feed> initialItems = items;
        return new ThrowableLoader<List<Feed>>(getActivity(), items) {

            @Override
            public List<Feed> loadData() throws Exception {
                try {
                    if(getActivity() != null) {
                        return serviceProvider.getFeeds(); //some method fetching some `feeds`
                    } else {
                        return Collections.emptyList();
                    }

                } catch (OperationCanceledException e) {
                    Activity activity = getActivity();
                    if (activity != null)
                        activity.finish();
                    return initialItems;
                }
            }
        };
    }

protected List<Feed> items = Collections.emptyList();

Btw ThrowableLoader class is implemented as follow

import android.content.Context;
    public abstract class ThrowableLoader<D> extends AsyncLoader<D> {


        private final D data;

        private Exception exception;

        /**
         * Create loader for context and seeded with initial data
         *
         * @param context
         * @param data
         */
        public ThrowableLoader(Context context, D data) {
            super(context);

            this.data = data;
        }

        @Override
        public D loadInBackground() {
            exception = null;
            try {
                return loadData();
            } catch (Exception e) {
                Ln.d(e, "Exception loading data");
                exception = e;
                return data;
            }
        }

        /**
         * @return exception
         */
        public Exception getException() {
            return exception;
        }

        /**
         * Clear the stored exception and return it
         *
         * @return exception
         */
        public Exception clearException() {
            final Exception throwable = exception;
            exception = null;
            return throwable;
        }

        /**
         * Load data
         *
         * @return data
         * @throws Exception
         */
        public abstract D loadData() throws Exception;
    }

and here's the `AsyncLoader`


import android.content.Context;
import android.support.v4.content.AsyncTaskLoader; 
public abstract class AsyncLoader<D> extends AsyncTaskLoader<D> {
    private D data;

    /**
     * Create async loader
     *
     * @param context
     */
    public AsyncLoader(Context context) {
        super(context);
    }

    @Override
    public void deliverResult(D data) {
        if (isReset())
            // An async query came in while the loader is stopped
            return;

        this.data = data;

        super.deliverResult(data);
    }

    @Override
    protected void onStartLoading() {
        if (data != null)
            deliverResult(data);

        if (takeContentChanged() || data == null)
            forceLoad();
    }

    @Override
    protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        data = null;
    }
}

Upvotes: 0

Views: 2107

Answers (1)

rbarriuso
rbarriuso

Reputation: 823

The problem is you are mixing android.support.v4.app.LoaderManager with android.app.LoaderManager.

I guess you want to use the support library and hence you're using the android.support.v4.app.Fragment class (those imports are missing), therefore you should not do the ((android.app.LoaderManager.LoaderCallbacks<Object>)this) cast but just implement the android.support.v4.app.LoaderManager.LoaderCallbacks<List<Feed>> interface in your android.support.v4.app.Fragment and pass it without cast.

Upvotes: 1

Related Questions