Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple loaders in same activity

Tags:

java

android

I have two custom built loaders inherited from AsyncTaskLoader which I would like to use in my activity. Each of them returns result of different type. To use my activity for a callback I must implement two interfaces:

implements LoaderCallbacks<GetSyncListDataResult>, LoaderCallbacks<ErrorResult>

However, trying to implement required methods in the same class I end up with duplicate method error and erasure(???) error:

// Methods for the first loader
public Loader<GetSyncListDataResult> onCreateLoader(int ID, Bundle bundle) ...
public void onLoaderReset(Loader<GetSyncListDataResult> loader) ...
public void onLoadFinished(Loader<GetSyncListDataResult> loader, GetSyncListDataResult result) ...

// Methods for the second loader
public Loader<ErrorResult> onCreateLoader(int ID, Bundle bundle) ...
public void onLoaderReset(Loader<ErrorResult> loader) ...
public void onLoadFinished(Loader<ErrorResult> loader, ErrorResult result) ...

Obviously, the methods are clashing and I need an easy way how to resolve this. What would be the proper way of resolving this?

like image 917
Dusan Avatar asked Mar 26 '13 17:03

Dusan


2 Answers

The correct answer is as per @dymmeh's comment, i.e. not for the Activity to implement two LoaderCallbacks interfaces but for the activity to contain two LoaderCallbacks implementations. By way of example: initialise your LoaderCallbacks fields in your activity...

private LoaderCallbacks<GetSyncListDataResult> dataResultLoaderListener
  = new LoaderCallbacks<GetSyncListDataResult>() { ...methods here... };

private LoaderCallbacks<ErrorResult> errorResultLoaderListener
  = new LoaderCallbacks<ErrorResult>() { ...methods here... };

... and declare your loader ids...

private static final int DATA_RESULT_LOADER_ID = 1;
private static final int ERROR_RESULT_LOADER_ID = 2;

... and then initialise your loaders...

getLoaderManager().initLoader(DATA_RESULT_LOADER_ID, dataResultBundle, dataResultLoaderListener);
getLoaderManager().initLoader(ERROR_RESULT_LOADER_ID, errorResultBundle, errorResultLoaderListener);

... Done!

like image 105
Adil Hussain Avatar answered Nov 11 '22 20:11

Adil Hussain


class YourActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks {
// you still implements LoaderManager.LoaderCallbacks but without add <returnType> 
//and you have to cast the data into your needed data type in onLoadFinished()

    Private int loader1 = 1;
    private int loader2 =2;

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

    getSupportLoaderManager().initLoader(REVIEW_LOADER, null, this);
    getSupportLoaderManager().initLoader(REVIEW_LOADER, null, this);
}
    @Override
    public Loader onCreateLoader(int id, Bundle args) {
        if (id == loader1 ) {

            //YourLoaderClass1 is you loaderClass where you implement onStartLoading and loadingInBackground() 
            return new YourLoaderClass1();  
        } else if (id == loader2 ) {

            return new YourLoaderClass2();
        }
        return null;
    }

    @Override
    public void onLoadFinished(Loader loader, Object data) {
        int id = loader.getId();// find which loader you called
        if (id == loader1 ) {

            yourMethod1((List< >) data); // eg. cast data to List<String>
        } else if (id == loader2 ) {
            yourMethod1((String) data); // eg. cast data to String
        }
    }

    @Override
    public void onLoaderReset(Loader loader) {
        int id = loader.getId();
        if (id == loader1 ) {

        } else if (id == loader2 ) {

        }
    }
}

My Github example

like image 29
Xianwei Avatar answered Nov 11 '22 20:11

Xianwei