问题描述
我在我的应用程序中使用了一个加载器,根据我从使用这个加载器对联系人执行的查询中得到的结果,我执行了一些计算并将它们存储回 Sqlite 数据库中.我希望这个操作是异步的,但是我在使用异步任务之间感到困惑,因为我有很多不同的数据类型要返回,或者我应该使用简单的处理程序还是 AsyncTaskLoader,我希望它很简单,因为我是新手装载机.我试图四处搜索 AsyncTaskLoader 的示例,但似乎火箭科学,在我的场景中,这三个中任何一个的基本和简单的功能示例都会有很大帮助.
I am using a Loader in my application and based on the result I get from the query I perform on COntacts using this Loader I perform some calculations and store them back in a Sqlite DB. I want this operation to be Asynchronous, however I am confused between using an Async task, as I have lot of different data types to return or should I use a simple handler or an AsyncTaskLoader, I want it to be simple as I am new to Loaders. I tried to search around for examples of AsyncTaskLoader but it seems rocket science, a basic and simple functional example of any of the three in the context of my scenario would be a lot helpful.
推荐答案
如果你想使用 AsyncTaskLoader,这里有一个不错的样本给你.
If you wish to use AsyncTaskLoader, here's a nice sample for you.
我决定制定一个更简单的解决方案(基于 这个 repo强>):
I've decided to make a simpler solution (based on this repo):
public abstract class AsyncTaskLoaderEx<T> extends AsyncTaskLoader<T> {
private static final AtomicInteger sCurrentUniqueId = new AtomicInteger(0);
private T mData;
public boolean hasResult = false;
public static int getNewUniqueLoaderId() {
return sCurrentUniqueId.getAndIncrement();
}
public AsyncTaskLoaderEx(final Context context) {
super(context);
onContentChanged();
}
@Override
protected void onStartLoading() {
if (takeContentChanged())
forceLoad();
//this part should be removed from support library 27.1.0 :
//else if (hasResult)
// deliverResult(mData);
}
@Override
public void deliverResult(final T data) {
mData = data;
hasResult = true;
super.deliverResult(data);
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
if (hasResult) {
onReleaseResources(mData);
mData = null;
hasResult = false;
}
}
protected void onReleaseResources(T data) {
//nothing to do.
}
public T getResult() {
return mData;
}
}
用法:
在您的活动中:
getSupportLoaderManager().initLoader(TASK_ID, TASK_BUNDLE, new LoaderManager.LoaderCallbacks<Bitmap>() {
@Override
public Loader<Bitmap> onCreateLoader(final int id, final Bundle args) {
return new ImageLoadingTask(MainActivity.this);
}
@Override
public void onLoadFinished(final Loader<Bitmap> loader, final Bitmap result) {
if (result == null)
return;
//TODO use result
}
@Override
public void onLoaderReset(final Loader<Bitmap> loader) {
}
});
内部静态类,或者普通类:
inner static class , or a normal class:
private static class ImageLoadingTask extends AsyncTaskLoaderEx<Bitmap> {
public ImageLoadingTask (Context context) {
super(context);
}
@Override
public Bitmap loadInBackground() {
//TODO load and return bitmap
}
}
更新:从支持库 27.1.0 开始,事情发生了一些变化(链接 这里) :
在27.1.0版本中,每次Activity都会调用onStartLoading()开始了.由于您在 onStartLoading() 中调用了 deliveryResult(),您触发 onLoadFinished().这是按预期工作.
您应该从 onStartLoading() 中删除对 deliveryResult() 的调用因为不需要(加载器已经提供了计算结果loadInBackground() 无需您进行任何额外工作.
You should remove your call to deliverResult() from onStartLoading() as it is not needed (Loaders already deliver results computed in loadInBackground() without any additional work needed on your part).
我已针对此更改更新了上面的代码.
I've updated the code above for this change.
更新后的 kotlin 版本可以在此处找到.
Updated, kotlin version can be found here.
这篇关于AsyncTaskLoader 基本示例.(安卓)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!