标签: android-loader

是否仍然建议在后台加载listView项目使用AsyncTask?

背景

我听说有一些新的解决方案可以在后台加载数据,这比AsyncTask(比如加载器)更值得推荐.

问题

AsyncTasks很棒且易于使用.但是,它有一些局限性:

  1. 类本身必须进行修改,因为它受到待处理任务数量的限制(约256左右).当然,在listView的适配器中,如果不需要,我总是取消任务(例如,当我需要更新用于其他项目的视图时).

  2. 在重新创建活动/片段时,我还必须全部取消它们(或以不同的方式处理).

  3. 由于1和2,我需要管理它们并参考所有这些

  4. AsyncTask使用一个任务队列,有时我需要使用堆栈,所以我不得不创建自己的AsyncTask类,而不是使用堆栈.

这个问题

是否有AsyncTask的替代品?

我知道之前曾在某些帖子中提到这个问题(比如这里),但我在想是否有一种新的通用方法可以在后台加载数据来替换asyncTask.

关于Loaders,我认为这个想法是它们用于数据库和contentProviders,但它们是否也可以用于从Internet上加载(例如)数据(如图像文件)?

还有一个很好的样本由谷歌(这里称为"bitmapFun"),根据我所看到的使用AsyncTask(甚至扩展它,可能是因为我提到的相同的原因).但也许我也错过了一些东西?

android android-listview android-asynctask android-loader

6
推荐指数
1
解决办法
2582
查看次数

使用CursorLoader在填充列表视图之前显示进度指示器

在我的列表视图没有填充数据库数据时,有什么更好的方法来显示进度指示器?

我找到了一些如何使用assynctask执行此操作的示例,但在我的情况下,我使用Loader/ CursorLoader.

public class TestActivity extends SherlockFragmentActivity implements
    LoaderCallbacks<Cursor> {

SimpleCursorAdapter mAdapter;
ListView mListView;

private static final String[] UI_BINDING_FROM = new String[] {
        TestDBAdapter.KEY_NAME, TestDBAdapter.KEY_ICON };

private static final int[] UI_BINDING_TO = new int[] { R.id.text, R.id.icon };

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_Test);

    mListView = (ListView) findViewById(R.id.listview);

    mAdapter = new TestAdapter(getApplicationContext(),
            R.layout.list_item_Test, null, UI_BINDING_FROM,
            UI_BINDING_TO, 0);

    mListView.setAdapter(mAdapter);

    getSupportLoaderManager().initLoader(0, null, this);

}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {


    Uri uri = ContentProviderTest.CONTENT_URI; …
Run Code Online (Sandbox Code Playgroud)

android android-cursorloader android-loader

6
推荐指数
1
解决办法
8514
查看次数

restartLoader和onContentChanged之间的区别

目前,我有一个装载机

@Override
public Loader<List<HomeMenuRowInfo>> onCreateLoader(int arg0, Bundle bundle) {
    return new HomeMenuRowInfosLoader(this.getSherlockActivity());
}
Run Code Online (Sandbox Code Playgroud)

有时,由于内容更改,我需要让加载程序重新加载.我会做的.

this.getLoaderManager().getLoader(0).onContentChanged();
Run Code Online (Sandbox Code Playgroud)

但是,我希望onCreateLoader在内容更改时将一些其他捆绑信息传递给回调.我意识到通过使用onContentChanged,没有办法这样做.

我能搞清楚的唯一方法是

this.getLoaderManager().restartLoader(0, bundle, this);
Run Code Online (Sandbox Code Playgroud)

我想知道,是否有任何重大分歧Loader的行为,使用的restartLoader不是onContentChanged,除了捆绑传递的能力吗?

android android-loadermanager android-loader

6
推荐指数
1
解决办法
2085
查看次数

告诉Android AsyncTaskLoader以检索更多数据

让我首先说这不是关于滚动ListViews的问题.我不想知道如何判断用户何时滚动到列表的底部,所以请不要给我这个问题的答案,或者将其标记为重复.

我正在使用一个扩展AsyncTaskLoader的类来使用来自Web服务的数据填充ListView.

最初,我加载50件物品,一切都很好.我需要知道如何告诉Loader以递增方式加载下50个项目.我理解在ListView代码中要执行此操作,但我无法找出告诉Loader我想要加载更多数据而不重置它并再次加载所有内容的最佳方法.

再说一次,澄清一下,我在这里要解决的问题只是通知加载器需要加载更多数据.它已经知道如何在第二次调用loadInBackground()时加载更多数据,并且ListView已经知道在何时/何时通知Loader,问题是如何.

一些相关代码:

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);

    m_adapter = new SearchAdapter(getActivity());
    setListAdapter(m_adapter);

    // if the loader doesn't already exist, one will be created
    // otherwise the existing loader is reused so we don't have
    // to worry about orientation and other configuration changes
    getLoaderManager().initLoader(SEARCH_LOADER_ID, null, this);
}

@Override
public Loader<List<Result>> onCreateLoader(int id, Bundle args)
{
    String query = args != null ? args.getString(QUERY_KEY) : "";
    return new SearchLoader(getActivity(), query); …
Run Code Online (Sandbox Code Playgroud)

android android-loadermanager android-loader

6
推荐指数
1
解决办法
1899
查看次数

添加1000的标记到Android谷歌地图

我正在开发一个基于GoogleMap的Android应用程序.
我需要在地图上显示1000个标记.
目前,我从SQLite数据库加载器中检索每个标记的纬度和经度,并在public void onLoadFinished(final Loader loader, final Cursor cursor)方法中添加标记.
这种方法虽然提供了非常糟糕的用户体验,因为当我添加标记时应用程序没有响应.
如何在googlemap中添加1000个标记并保持我的应用程序响应?
因为我必须在主UI线程上将标记添加到地图.

android android-loader google-maps-android-api-2

6
推荐指数
1
解决办法
2221
查看次数

当一个活动因配置更改而被破坏时,它的Loaders也会被销毁吗?

装载机开发者指南,

在配置更改后重新创建时,它们会自动重新连接到最后一个加载器的光标.因此,他们不需要重新查询他们的数据.

在这篇关于装载机的博客文章中,

当一个Activity被销毁时,Activity指示它的LoaderManager销毁并关闭它的Loaders(以及与它们相关的任何资源,比如Cursor).

问题是哪一个是正确的?当一个活动因配置更改而被销毁时,(1)其Loaders(2)与其Loaders关联的资源(例如a)会发生什么Cursor.

android android-configchanges android-activity android-loadermanager android-loader

6
推荐指数
0
解决办法
1106
查看次数

使用自定义Loader时,未在ViewPager片段上调用onResume()

精简版:

我有保持一个片段ViewPager显示其他两个片段,让我们称他们FragmentOneFragmentTwo.当启动应用程序时,该应用程序FragmentOne是可见的并且FragmentTwo在屏幕外,只有在向左滑动视图时才可见.

通常onStart(),onResume()应用程序启动后立即立即调用这两个片段.

我遇到的问题是当FragmentOne启动自定义时,Loader然后onResume()FragmentTwo它变得完全可见之前不会被调用.

显示问题的屏幕截图

问题:

这是我的代码问题还是Android支持库中的错误?(该库的修订版12没有出现问题,它从修订版13开始.)

如果它是修订版13和18中的错误,是否有解决方法?

我的自定义有问题Loader吗?

长版:

我已经构建了一个演示该问题的示例应用程序.我试图将代码减少到最低限度,但它仍然很多,所以请耐心等待.

我有一个MainActivity加载a MainFragment创建一个ViewPager.对于我的应用程序来说,ViewPager由Fragment而不是Activity维护是很重要的.

MainFragment创建一个FragmentPagerAdapter反过来创建片段FragmentOneFragmentTwo.

让我们从有趣的位开始,两个片段:

FragmentOne是一个ListFragment使用自定义Loader加载内容:

public class FragmentOne extends ListFragment implements LoaderCallbacks<List<String>> {
    private ArrayAdapter<String> adapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1);
        setListAdapter(adapter); …
Run Code Online (Sandbox Code Playgroud)

android android-viewpager android-loader android-support-library

5
推荐指数
1
解决办法
7634
查看次数

正确通知AsyncTaskLoader关于来自后台线程的数据更改

我想AsyncTaskLoader为我的自定义数据源实现:

public class DataSource {
    public interface DataSourceObserver {
        void onDataChanged();
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

DataSource将保留已注册观察员的名单,并将通知他们有关变化的信息.CustomLoader将实施DataSourceObserver.问题是如何正确通知,CustomLoader因为Loader.onContentChanged()必须从UI线程调用,但在我的情况下,DataSource操作(和调用DataSourceObserver.onDataChanged())将从后台线程完成.

更新了Selvin提示的想法:

public class CustomLoader extends AsyncTaskLoader<...> implements DataSource.DataSourceObserver {
    private final Handler observerHandler;

    public CustomLoader(Context context) {
        super(context);
        observerHandler = new Handler()
    }

    @Override
    public void onDataChanged() {
        observerHandler.post(new Runnable() {
            @Override
            public void run() {
                onContentChanged();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

android android-loader

5
推荐指数
1
解决办法
2258
查看次数

Android 加载进度条,带有自定义图像和进度指示器

如果这看起来微不足道,我深表歉意。

我一直在开发我的第一个 Android 应用程序,并希望获得有关实现附加加载/启动屏幕的最佳方法的建议。

我的设计师想出了加载/启动屏幕,但我不知道如何实现它。

  1. 我是否要求设计师创建一个可以直接播放的 .gif 图像,或者
  2. 我是否在应用程序中以这样的方式进行编码:进度条和自行车从左向右移动,完成任务(远程异步任务)后,我手动将其推至 100%,并将图像推至最右侧以指示完成。

请注意,自行车从左侧开始并继续向右,并带有进度指示器和%。

选项 2 是否可行?如果可以,请您指出我可以用作指南的任何资源。

加载启动图像

谢谢

android android-animation android-loader

5
推荐指数
1
解决办法
9631
查看次数

Loader <Cursor>仅加载选定的行+下一行

活动A中,我正在加载一个包含我表中所有值的列表,并设置了一个setOnItemClickListener来启动活动B并通过发送数据发送带有所选项的id [ 1 ] 的uri

[ 1 ] Uri currentTestUri = ContentUris.withAppendedId(TestEntry.CONTENT_URI, id);

活动B中,我的onCreateLoader包含投影:

String[] projection = {
       TestEntry._ID,
       TestEntry.COLUMN_TEST_ONE,
       TestEntry.COLUMN_TEST_TWO}
Run Code Online (Sandbox Code Playgroud)

...带有return语句

return new CursorLoader(this,  
    mCurrentTestUri, //Got this from Activity A         
    projection,             
    null,                   
    null,                   
    null);  
Run Code Online (Sandbox Code Playgroud)

我的onLoadFinished看起来像这样:

if (cursor.moveToFirst()) {
      int oneColumnIndex = cursor.getColumnIndex(TestEntry.COLUMN_TEST_ONE);
      int twoColumnIndex = cursor.getColumnIndex(TestEntry.COLUMN_TEST_TWO);

      String currentOne = cursor.getString(oneColumnIndex);
      String currentTwo = cursor.getString(twoColumnIndex);

      textViewOne.setText(currentOne);
      textViewTwo.setText(currentTwo);
}
Run Code Online (Sandbox Code Playgroud)

到目前为止一切顺利,现在我希望显示下一行(右下方)的值,但是使用不同的投影(我只需要_IDCOLUMN_TEST_ONE)并且onLoadFinished显示COLUMN_TEST_ONE的值textViewThree.

[两行的值应该同时显示,而不是一个或另一个]

我可以使用[ …

sqlite android android-cursorloader android-loader android-sqlite

5
推荐指数
1
解决办法
295
查看次数