Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android AsyncTaskLoader基本示例。(安卓)_Android_Android Asynctask_Android Handler - Fatal编程技术网

Android AsyncTaskLoader基本示例。(安卓)

Android AsyncTaskLoader基本示例。(安卓),android,android-asynctask,android-handler,Android,Android Asynctask,Android Handler,我在我的应用程序中使用了一个加载器,根据我使用这个加载器对联系人执行的查询结果,我执行一些计算并将它们存储回Sqlite数据库。我希望这个操作是异步的,但是我混淆了使用异步任务,因为我有很多不同的数据类型要返回,或者我应该使用简单的处理程序或AsyncTaskLoader,我希望它是简单的,因为我是新的加载程序。我试图搜索AsyncTaskLoader的示例,但在我的场景中,火箭科学(rocket science)似乎是这三个示例中任何一个的基础和简单功能示例都会非常有用 由于蜂巢和v4兼容库,

我在我的应用程序中使用了一个加载器,根据我使用这个加载器对联系人执行的查询结果,我执行一些计算并将它们存储回Sqlite数据库。我希望这个操作是异步的,但是我混淆了使用异步任务,因为我有很多不同的数据类型要返回,或者我应该使用简单的处理程序或AsyncTaskLoader,我希望它是简单的,因为我是新的加载程序。我试图搜索AsyncTaskLoader的示例,但在我的场景中,火箭科学(rocket science)似乎是这三个示例中任何一个的基础和简单功能示例都会非常有用

由于蜂巢和v4兼容库,因此可以使用
AsyncTaskLoader
。据我所知,
AsyncTaskLoader
可以通过屏幕翻转等配置更改生存下来。但是使用
AsyncTask
可能会搞乱配置更改

关键信息:
AsyncTaskLoader
Loader
的子类。该类执行与AsyncTask相同的功能,但更好一些,它在处理配置更改(屏幕方向)时也很有用

这里给出了一个很好的例子和解释。

谷歌在API文档中有一个很好的例子。 Android设计模式提供了一些更详细的细节和加载程序背后的推理


本教程肯定会对您有所帮助

如果您希望使用AsyncTaskLoader,这是一个很好的示例

编辑:我决定制作一个更简单的解决方案(基于):

公共抽象类AsyncTaskLoaderEx扩展了AsyncTaskLoader{
私有静态最终AtomicInteger sCurrentUniqueId=新的AtomicInteger(0);
私有T-mData;
公共布尔值hasResult=false;
公共静态int getNewUniqueLoaderId(){
返回sCurrentUniqueId.getAndIncrement();
}
公共AsyncTaskLoaderEx(最终上下文){
超级(上下文);
onContentChanged();
}
@凌驾
开始加载时受保护的void(){
if(takeContentChanged())
力载荷();
//该零件应从支架库27.1.0中移除:
//否则如果(hasResult)
//交付结果(mData);
}
@凌驾
公共无效交付结果(最终T数据){
mData=数据;
hasResult=true;
super.deliverResult(数据);
}
@凌驾
受保护的void onReset(){
super.onReset();
onStopLoading();
如果(结果){
onReleaseResources(mData);
mData=null;
hasResult=false;
}
}
受保护的无效onReleaseResources(T数据){
//无事可做。
}
公共T getResult(){
返回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) {
            }
        });
getSupportLoaderManager().initLoader(任务ID,任务包,新的LoaderManager.LoaderCallbacks(){
@凌驾
公共加载器onCreateLoader(最终int-id,最终Bundle-args){
返回新的ImageLoadingTask(MainActivity.this);
}
@凌驾
public void onLoadFinished(最终加载程序,最终位图结果){
如果(结果==null)
返回;
//待办事项使用结果
}
@凌驾
公共无效onLoaderReset(最终加载程序){
}
});
内部静态类或普通类:

private static class ImageLoadingTask extends AsyncTaskLoaderEx<Bitmap> {

    public ImageLoadingTask (Context context) {
        super(context);
    }

    @Override
    public Bitmap loadInBackground() {
        //TODO load and return bitmap
    }
}
私有静态类ImageLoadingTask扩展了AsyncTaskLoaderEx{
公共ImageLoadingTask(上下文){
超级(上下文);
}
@凌驾
公共位图加载背景(){
//TODO加载并返回位图
}
}

更新:从支持库27.1.0开始,情况发生了一些变化(链接):

在版本27.1.0中,每次激活活动时都会调用onStartLoading() 开始了。由于在onStartLoading()中调用deliverResult(),因此 触发器onLoadFinished()。这是工作的预期

您应该从onStartLoading()中删除对deliverResult()的调用 因为它不是必需的(装载机已经在 loadInBackground(),无需您进行任何额外工作)

我已经为这一更改更新了上面的代码


编辑:
更新后的kotlin版本可以找到。

我喜欢这个简单的例子


我更喜欢用Android。这很容易

Task.callInBackground(新的Callable(){
公开作废通知(){
//做一大堆事情。
}
}).继续使用(…);
下面是实现
AsyncTaskLoader
的分步教程。或者

  • 在MainActivity上实现
    LoaderManager.LoaderCallbacks
    ,并创建一个
    static int
    ,以唯一标识加载程序,并创建一个字符串键将字符串url传递给加载程序

    public class MainActivity extends AppCompatActivity 
                 implements LoaderManager.LoaderCallbacks<String>{
        public static final int OPERATION_SEARCH_LOADER = 22;
        public static final String OPERATION_QUERY_URL_EXTRA = "query";
    //...}
    
  • inside
    onCreateLoader()
    返回一个新的
    AsyncTaskLoader
    作为匿名内部类,其中
    this
    作为构造函数的参数,并在匿名内部重写
    loadInBackground
    onStartLoading
    内部阶级

    @Override
    public Loader<String> onCreateLoader(int id, final Bundle args) {
        return new AsyncTaskLoader<String>(this) {
            @Override
            public String loadInBackground() {
                //Think of this as AsyncTask doInBackground() method, here you will actually initiate Network call
                return null;
            }
    
            @Override
            protected void onStartLoading() {
               //Think of this as AsyncTask onPreExecute() method,start your progress bar,and at the end call forceLoad(); 
               forceLoad();
            }
        };
    }
    
  • onCreate
    内部,使用操作\u SEARCH\u loader作为ID初始化加载程序,bundle为null,上下文为null

    getSupportLoaderManager().initLoader(OPERATION_SEARCH_LOADER, null, this);
    
  • 现在,无论何时何地,只要您想触发加载程序,就调用这个方法

    private void makeOperationSearchQuery(String url) {
    
        // Create a bundle called queryBundle
        Bundle queryBundle = new Bundle();
        // Use putString with OPERATION_QUERY_URL_EXTRA as the key and the String value of the URL as the value
        queryBundle.putString(OPERATION_QUERY_URL_EXTRA,url);
        // Call getSupportLoaderManager and store it in a LoaderManager variable
        LoaderManager loaderManager = getSupportLoaderManager();
        // Get our Loader by calling getLoader and passing the ID we specified
        Loader<String> loader = loaderManager.getLoader(OPERATION_SEARCH_LOADER);
        // If the Loader was null, initialize it. Else, restart it.
        if(loader==null){
            loaderManager.initLoader(OPERATION_SEARCH_LOADER, queryBundle, this);
        }else{
            loaderManager.restartLoader(OPERATION_SEARCH_LOADER, queryBundle, this);
        }
    }
    
    private void makeOperationSearchQuery(字符串url){
    //创建一个名为queryBundle的包
    Bundle queryBundle=新Bundle();
    //使用putString,操作\u QUERY\u URL\u EXTRA作为键,URL的字符串值作为值
    putString(操作\u查询\u URL\u额外,URL);
    //调用getSupportLoaderManager并将其存储在LoaderManager变量中
    LoaderManager LoaderManager=getSupportLoaderManager();
    //通过调用getLoader并传递我们指定的ID来获取我们的Loader
    
    @Override
    public Loader<String> onCreateLoader(int id, final Bundle args) {
        //Here we will initiate AsyncTaskLoader
        return null;
    }
    
    @Override
    public void onLoadFinished(Loader<String> loader, String operationResult) {
        //Think of this as AsyncTask onPostExecute method, the result from onCreateLoader will be available in operationResult variable and here you can update UI with the data fetched.
        Log.d("MAINACTIVITY","result : "+ operationResult);
    }
    
    @Override
    public void onLoaderReset(Loader<String> loader) {
        //Don't bother about it, Android Studio will override it for you
    }
    
    @Override
    public Loader<String> onCreateLoader(int id, final Bundle args) {
        return new AsyncTaskLoader<String>(this) {
            @Override
            public String loadInBackground() {
                //Think of this as AsyncTask doInBackground() method, here you will actually initiate Network call
                return null;
            }
    
            @Override
            protected void onStartLoading() {
               //Think of this as AsyncTask onPreExecute() method,start your progress bar,and at the end call forceLoad(); 
               forceLoad();
            }
        };
    }
    
     @Override
        public String loadInBackground() {
            String url = args.getString(OPERATION_QUERY_URL_EXTRA);//This is a url in string form 
            if (url!=null&&"".equals(url)) {
                return null;//if url is null, return
            }
            String operationResult="";
            try {
                operationResult = NetworkUtils.getResponseFromHttpUrl(url);//This just create a HTTPUrlConnection and return result in strings
            } catch (IOException e) {
                e.printStackTrace();
            }
            return operationResult;
        }
    
    getSupportLoaderManager().initLoader(OPERATION_SEARCH_LOADER, null, this);
    
    private void makeOperationSearchQuery(String url) {
    
        // Create a bundle called queryBundle
        Bundle queryBundle = new Bundle();
        // Use putString with OPERATION_QUERY_URL_EXTRA as the key and the String value of the URL as the value
        queryBundle.putString(OPERATION_QUERY_URL_EXTRA,url);
        // Call getSupportLoaderManager and store it in a LoaderManager variable
        LoaderManager loaderManager = getSupportLoaderManager();
        // Get our Loader by calling getLoader and passing the ID we specified
        Loader<String> loader = loaderManager.getLoader(OPERATION_SEARCH_LOADER);
        // If the Loader was null, initialize it. Else, restart it.
        if(loader==null){
            loaderManager.initLoader(OPERATION_SEARCH_LOADER, queryBundle, this);
        }else{
            loaderManager.restartLoader(OPERATION_SEARCH_LOADER, queryBundle, this);
        }
    }
    
      private void loadContent() {
        getLoaderManager().initLoader(1000, new Bundle(), 
          new LoaderManager.LoaderCallbacks<List<String>>() {
    
          @Override
          public Loader<List<String>> onCreateLoader(int id, Bundle args) {
            return new AsyncTaskLoader<List<String>>(MainActivity.this.getApplicationContext()) {
    
              @Override
              public List<String> loadInBackground() {
                Log.i("B", "Load background data ");
                ArrayList<String> data = new ArrayList<>();
                for (int i = 0; i < 5000; i++) {
                  data.add("Data." + i + " " + System.currentTimeMillis());
                }
                try {
                  Thread.sleep(5000);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
                return data;
              }
            };
          }
    
          @Override
          public void onLoadFinished(Loader<List<String>> loader, List<String> data) {
            Log.i("B", "Here are your data loaded" + data);
            if (!loader.isAbandoned()) {
              mAdapter.setData(data); // Read also about RecyclerView
            }
          }
    
          @Override
          public void onLoaderReset(Loader<List<String>> loader) {
            Log.i("B", "Loader reset");
          }
        }).forceLoad();
      }
    
      @Override
      protected void onDestroy() {
        // Abandon the loader so that it should not attempt to modify already dead GUI component
        getLoaderManager().getLoader(1000).abandon();
        super.onDestroy();
      }