29

我有两个定制的加载AsyncTaskLoader器继承自我想在我的活动中使用。它们中的每一个都返回不同类型的结果。要将我的活动用于回调,我必须实现两个接口:

implements LoaderCallbacks<GetSyncListDataResult>, LoaderCallbacks<ErrorResult>

但是,尝试在同一个类中实现所需的方法最终会出现重复方法错误和擦除(???)错误:

// 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) ...

显然,这些方法是冲突的,我需要一种简单的方法来解决这个问题。解决这个问题的正确方法是什么?

4

4 回答 4

52

正确答案是根据@dymmeh 的评论,即不是为了Activity实现两个LoaderCallbacks接口,而是为了让活动包含两个LoaderCallbacks实现。例如:在您的活动中初始化您的LoaderCallbacks字段...

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

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

...并声明您的加载程序ID...

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

...然后初始化您的装载机...

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

... 完毕!

于 2013-12-30T12:42:08.003 回答
7
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 ) {

        }
    }
}

我的Github 示例

于 2017-09-08T22:28:09.987 回答
0

实际上,如果您LoaderManager.LoaderCallbacks<T> 在 Activity 类上实现,并使用特定的加载器 id,使用结果进行操作,它会更简单。这样,您的代码更具可读性和功能性(因为内部加载程序回调的接口实现不再重复)。

例如 :

    public class JobListActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<NetworkResult> {

        public static final  int    SUBMIT_RISK_ASSESSMENT_LOADER = 546;
        public static final  int    LOAD_RISK_ASSESSMENT_LOADER   = 1546;

        public Loader<NetworkResult> onCreateLoader(int id, @Nullable Bundle args) {
            if (id == SUBMIT_RISK_ASSESSMENT_LOADER) {
                return new NetworkLoader( this, args.getString( NetworkLoader.URL_EXTRA ), NetworkLoader.POST, args.getString( BODY ), false ));
            } else if (id == LOAD_RISK_ASSESSMENT_LOADER) {
                return new NetworkLoader( this, args.getString( NetworkLoader.URL_EXTRA ), NetworkLoader.GET, null, false ) );
            }

            return null;
        }

        @Override
        public void onLoadFinished(@NonNull Loader<NetworkResult> loader, NetworkResult data) {
            if (data == null) {
                return;
            }

            Crashlytics.log( Log.INFO, TAG, "onLoadFinished with data [" + data + "]" );

            if (loader.getId() == SUBMIT_RISK_ASSESSMENT_LOADER) {
                    doSemethingElse(data);
            } else if (loader.getId() == LOAD_RISK_ASSESSMENT_LOADER) {
                    doSemethingElse(data);
            }
            LoaderManager.getInstance( this ).destroyLoader( loader.getId() );
    }
于 2019-08-21T12:11:07.863 回答
-1

这是没有必要的。实现 LoaderManager.LoaderCallbacks。然后,每次初始化加载程序时,给它一个唯一的 ID。在回调中,您可以检测导致回调的加载程序的 ID 并采取适当的操作。

那是

class MyLoader extends Activity implements LoaderManager.LoaderCallbacks<GetSyncDataResult> {
...
private static final int LOADER1 = 1;
private static final int LOADER2 = 2;
...
getLoaderManager().initLoader(LOADER1, null, this);
...
getLoaderManager().initLoader(LOADER2, null, this);
...

public Loader<GetSyncDataResult> onCreateLoader(int loaderId, Bundle args) {

    switch (loaderId) {

    case LOADER1: ...
    case LOADER2: ...
}
...

等等。

于 2013-03-26T19:09:39.800 回答