29

AsyncTaskLoaderアクティビティで使用したい2つのカスタムビルドローダーが継承されています。それぞれが異なるタイプの結果を返します。コールバックにアクティビティを使用するには、2つのインターフェイスを実装する必要があります。

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のコメントによるものです。つまり、 2つのインターフェースActivityを実装するためではなく、アクティビティに2つの実装を含めるためです。例として:アクティビティのフィールドを初期化します...LoaderCallbacksLoaderCallbacksLoaderCallbacks

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 に答える