java 同一活动中的多个加载器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15643907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple loaders in same activity
提问by Dusan
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:
我有两个自定义构建的加载器AsyncTaskLoader
,我想在我的活动中使用它们。他们每个人都返回不同类型的结果。要将我的活动用于回调,我必须实现两个接口:
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?
显然,这些方法存在冲突,我需要一个简单的方法来解决这个问题。解决这个问题的正确方法是什么?
回答by Adil Hussain
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 containtwo LoaderCallbacks
implementations. By way of example: initialise your LoaderCallbacks
fields in your activity...
正确答案是根据@dymmeh 的评论,即不是为了Activity
实现两个LoaderCallbacks
接口,而是为了包含两个LoaderCallbacks
实现的活动。举例来说:LoaderCallbacks
在您的活动中初始化您的字段......
private LoaderCallbacks<GetSyncListDataResult> dataResultLoaderListener
= new LoaderCallbacks<GetSyncListDataResult>() { ...methods here... };
private LoaderCallbacks<ErrorResult> errorResultLoaderListener
= new LoaderCallbacks<ErrorResult>() { ...methods here... };
... and declare your loader ids...
...并声明您的加载程序ID ...
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!
... 完毕!
回答by Xianwei
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 ) {
}
}
}
回答by dobrivoje
Actually it's simpler if you implement LoaderManager.LoaderCallbacks<T>
on your Activity class, and using specific loaders ids, manipulate with result.
This way, your code is more readable and functional (because there is no more duplication of interface implementations of inner loader callbacks).
实际上,如果您LoaderManager.LoaderCallbacks<T>
在 Activity 类上实现并使用特定的加载器 ID,并使用结果进行操作,则会更简单。这样,您的代码更具可读性和功能性(因为内部加载器回调的接口实现不再重复)。
For example :
例如 :
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() );
}
回答by Joe Malin
This isn't necessary. Implement LoaderManager.LoaderCallbacks. Then, each time you initialize a loader, give it a unique ID. In the callbacks, you can detect the ID of the loader that caused the callback and take the appropriate action.
这是没有必要的。实现 LoaderManager.LoaderCallbacks。然后,每次初始化加载器时,给它一个唯一的 ID。在回调中,您可以检测导致回调的加载程序的 ID 并采取适当的操作。
that is
那是
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: ...
}
...
and so forth.
等等。