首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AsyncTaskLoader基本示例。(Android)

AsyncTaskLoader基本示例。(Android)
EN

Stack Overflow用户
提问于 2013-11-29 05:50:51
回答 6查看 54K关注 0票数 23

我在我的应用程序中使用一个Loader,根据我使用这个Loader在COntacts上执行的查询所得到的结果,我执行一些计算,并将它们存储在一个Sqlite中。我希望这个操作是异步的,但是我混淆了使用异步任务,因为我有许多不同的数据类型要返回,或者我应该使用一个简单的处理程序或AsyncTaskLoader,我希望它是简单的,因为我对加载程序是新手。我试着四处寻找AsyncTaskLoader的例子,但似乎是火箭科学,在我的场景中,三个中的任何一个都有一个基本的、简单的函数示例,这将是非常有帮助的。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2014-03-27 00:00:43

如果您想使用AsyncTaskLoader,下面是为您提供了一个很好的示例。

编辑:我决定做一个更简单的解决方案(基于这个回购):

代码语言:javascript
复制
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;
    }
}

用法:

在你的活动中:

代码语言:javascript
复制
        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) {
            }
        });

内部静态类,或普通类:

代码语言:javascript
复制
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版本中,每次活动启动时都会调用onStartLoading()。由于在deliverResult()中调用了onStartLoading(),因此触发了onLoadFinished()。这是按计划进行的。 您应该将对deliverResult()的调用从onStartLoading()中删除,因为它是不需要的(加载程序已经交付了loadInBackground()中计算的结果,而不需要做任何额外的工作)。

为此,我更新了上面的代码。

编辑:更新,kotlin版本可以找到这里

票数 32
EN

Stack Overflow用户

发布于 2013-11-29 06:40:38

由于蜂窝和v4兼容性库,所以可以使用AsyncTaskLoader。据我所知,AsyncTaskLoader可以通过像屏幕翻转这样的配置变化来生存下来。但是使用AsyncTask,您可以处理配置更改。

关键信息:AsyncTaskLoaderLoader的子类。这个类执行与AsyncTask相同的功能,但更好的是,它在处理配置更改(屏幕方向)方面也很有用。

这里给出了一个很好的例子和解释。http://www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html

Google在API文档中有一个很好的例子。提供了一些更多的细节和装载机背后的推理。

本教程将明确地帮助你。http://www.javacodegeeks.com/2013/08/android-custom-loader-to-load-data-directly-from-sqlite-database.html

票数 12
EN

Stack Overflow用户

发布于 2017-06-10 13:20:58

下面是一步一步地实现AsyncTaskLoader的教程。或者 5~6成熟上查看同一篇文章

  1. LoaderManager.LoaderCallbacks<String>上实现MainActivity,并创建一个static int来唯一地标识加载程序,并创建一个字符串键将字符串url传递给加载程序 公共类MainActivity扩展AppCompatActivity实现LoaderManager.LoaderCallbacks{公共静态最终int OPERATION_SEARCH_LOADER = 22;公共静态最终字符串OPERATION_QUERY_URL_EXTRA = "query";//.}
  2. 重写onCreateLoaderonLoadFinished和MainActivity中的onLoaderReset函数 @重载公共加载程序onCreateLoader(int,final Bundle args) {//在这里我们将启动AsyncTaskLoader返回null;}@重写公共无效onLoadFinished(加载器加载程序,字符串operationResult) {//将此视为AsyncTask onPostExecute方法,onCreateLoader的结果将在operationResult变量中可用,在这里您可以用获取的数据更新UI。Log.d("MAINACTIVITY",“结果:"+ operationResult);}@覆盖公共无效onLoaderReset(装载机加载程序){//不要费心,Android将为您重写它}
  3. onCreateLoader()内部,以this作为构造函数的参数,以匿名内部类的形式返回一个新的AsyncTaskLoader<String>,并在匿名内部类中重写loadInBackground & onStartLoading @覆盖公共加载器onCreateLoader(int id,final Bundle args) {返回新的AsyncTaskLoader( this ) {@重写公共字符串loadInBackground() {/将其视为AsyncTask doInBackground()方法,这里实际上将启动网络调用返回null;}@重写受保护的void onStartLoading() {//将其视为AsyncTask onPreExecute()方法,启动进度条,并在最后调用forceLoad();forceLoad();};}}
  4. loadInBackground内部,使用HTTPUrlConnection或OKHttp或您使用的任何东西进行网络调用。 @重写公共字符串loadInBackground() { String =loadInBackground是字符串形式的url,如果( url!= null &“.equals( url )){返回空;//如果url为空,则返回}字符串operationResult=”;尝试{ operationResult = NetworkUtils.getResponseFromHttpUrl(url);//这只是创建一个HTTPUrlConnection并返回字符串} catch (IOException e) { e.printStackTrace();}返回operationResult;}
  5. onCreate内部,使用OPERATION_SEARCH_LOADER作为ID初始化加载程序,对于包为null,对于上下文为null getSupportLoaderManager().initLoader(OPERATION_SEARCH_LOADER,null,此法);
  6. 现在调用此方法,无论何时何地,都要触发加载程序。 私有void ( String ){ //创建一个名为queryBundle bundle queryBundle =queryBundle()的捆绑包;//使用以OPERATION_QUERY_URL_EXTRA为键的putString作为键,使用URL的字符串值作为值makeOperationSearchQuery url);//调用getSupportLoaderManager并将其存储在一个loaderManager变量LoaderManager LoaderManager =getSupportLoaderManager()中;//通过调用getLoader并传递我们指定的loaderManager= loaderManager.getLoader(OPERATION_SEARCH_LOADER);的ID来获取加载程序//如果装载机为null,则初始化它。否则,重启它。如果( loaderManager.initLoader(OPERATION_SEARCH_LOADER,queryBundle,this);}loader==null{ loaderManager.restartLoader(OPERATION_SEARCH_LOADER,queryBundle,this);}

沃拉,你完成了,只是提醒你,NetworkUtils.getResponseFromHttpUrl(url);是我的自定义函数,它把字符串转换成URL,然后再用来创建HTTPUrlConnection

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20279216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档