【发布时间】:2013-08-14 13:51:10
【问题描述】:
在 ViewPager 管理的片段中使用 AsyncTaskLoaders 时遇到问题。 配置是这样的:
Fragment#1 - 从磁盘加载图片的加载器 Fragment#2 - 从磁盘加载自定义对象的加载器 Fragment#3 - 从网络加载 JSON 对象的加载器 片段#4 - 作为#3
如果我在 Fragment#1 中省略了加载程序,一切正常,如预期的那样。 但是,如果我尝试在 Fragment#1 中使用 Loader,所有其他 Loader 都不会调用每个片段中指定的 onLoadFinished 回调。我放了一点日志,我看到所有其他加载器都正确处理了 loadInBackground() 方法,但之后它们处于重置状态。
可能有最大数量的同时可用的加载器,或者加载的位图大小有问题?
每个片段都需要像这样在 onCreateView() 回调中初始化加载器
getLoaderManager().initLoader(STATS_LOADER_ID, null, this);
并实现 LoaderManager.LoaderCallbacks as this
@Override
public Loader<UserStats> onCreateLoader(int arg0, Bundle arg1) {
ProfileStatsLoader loader = new ProfileStatsLoader(getActivity(), userId);
loader.forceLoad();
return loader;
}
@Override
public void onLoadFinished(Loader<UserStats> loader, UserStats stats) {
Log.d(TAG, "onLoadFinished");
postLoadUI((ProfileStatsLoader) loader, stats);
}
@Override
public void onLoaderReset(Loader<UserStats> arg0) {
Log.d(TAG, "onLoaderReset");
}
第一个Loader(那很可能是其余三个失败的原因)代码是
public class ProfilePictureLoader extends AsyncTaskLoader<Bitmap> {
private static final String TAG = ProfilePictureLoader.class.getCanonicalName();
private User user;
private int maxSize;
private Bitmap bitmap;
private Throwable error;
public ProfilePictureLoader(Context context, User user, int maxSize) {
super(context);
this.user = user;
this.maxSize = maxSize;
}
public Throwable getError() {
return error;
}
public Bitmap getPicture() {
return bitmap;
}
@Override
public Bitmap loadInBackground() {
Log.d(TAG, "Loading bitmap for user " + user.getUuid());
Log.w(TAG, "Is reset at start? " + this.isReset());
ImageUtils iu = new ImageUtils(getContext());
String localProfilePicturePath = iu.loadBitmapURIForUser(user.getUuid());
// if the user has not a picture saved locally (for logged user) neither
// have never set a profile picture (for online users), return a null
// bitmap
if (localProfilePicturePath == null && !user.hasProfilePicture())
return null;
try {
if (user.isStoredLocally()) {
// load local profile image
bitmap = null;
if (localProfilePicturePath != null)
// load profilePictureMaxSize px width/height
bitmap = ImageUtils.decodeSampledBitmapFromPath(localProfilePicturePath, maxSize, maxSize);
} else {
// download remotely
bitmap = UserRESTClient.downloadUserPicture(user.getUuid(), UserRESTClient.PICTURE_MEDIUM_SIZE);
}
return bitmap;
} catch (Throwable t) {
Log.e(TAG, "Error loading bitmap for user " + user.getUuid() + ": " + t);
t.printStackTrace();
error = t;
return null;
}finally{
Log.w(TAG, "Is reset? " + this.isReset());
}
}
}
【问题讨论】:
-
你能显示一些代码吗?
-
有很多代码但它是多余的,所以我刚刚编辑了只包含我认为相关的代码。但是,如果您认为需要更多代码,我会尝试在此处编写代码,而不会使问题难以理解。
-
如果代码很多,需要先缩小范围
-
Loaders和Fragments中的代码比较相似,所以这里只写了Loaders初始化和回调的相关部分。我编写的加载器只是重写了 loadInBackground() 方法来加载所需的数据(并且我已经验证了数据加载正确)。
-
(你的第一个加载器中可能有一些东西,顺便说一句,你为什么不把这个的代码放在这里?)
标签: android android-loadermanager android-loader