使用支持库从加载器更新FragmentList后应用程序崩溃

时间:2014-06-26 16:36:43

标签: java android android-listview android-listfragment android-support-library

我有一个使用Support Library v4的加载器,它用于在包含两个片段的Activity中加载ListView,一个包含ListView(它是ListFragment的扩展),另一个载有一个按钮(可以在加载程序执行工作时单击该按钮)。

该实现非常类似于AsyncTaskLoader的Android文档中提供的实现,它也通过加载器创建ListView,但监视部分除外,我的实现不需要监视更改:{ {3}}

由于应用程序支持API级别8,我使用FragmentActivity :: getSupportLoaderManager方法启动加载程序,如文档中所建议的那样,以保持支持。

http://developer.android.com/reference/android/content/AsyncTaskLoader.html

  

使用此类而不是新平台的内置片段和加载器支持时,必须分别使用getSupportFragmentManager()和getSupportLoaderManager()方法来访问这些功能。

作为从Fragment开始的加载器,我必须使用ListFragment :: getActivity方法来调用方法FragmentActivity :: getSupportLoaderManager,导致以下代码用于启动加载器:

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

应用程序运行正常,API高于8,但在第8级时,加载程序尝试在加载后在UI上呈现列表时崩溃(Loader :: onLoadFinished方法)。

调试我发现在适配器上调用ArrayAdapter<> :: addAll方法时崩溃了,这确认了问题在于呈现UI。此时,应用程序被抛出到SamplingProfilerIntegration类,其中与快照相关的内容正在尝试在类的静态部分完成:

/** Whether or not a snapshot is being persisted. */
private static final AtomicBoolean pending = new AtomicBoolean(false);

static {
    samplingProfilerMilliseconds = SystemProperties.getInt("persist.sys.profiler_ms", 0);
    samplingProfilerDepth = SystemProperties.getInt("persist.sys.profiler_depth", 4);
    if (samplingProfilerMilliseconds > 0) {
        File dir = new File(SNAPSHOT_DIR);
        dir.mkdirs();
        // the directory needs to be writable to anybody to allow file writing
        dir.setWritable(true, false);
        // the directory needs to be executable to anybody to allow file creation
        dir.setExecutable(true, false);
        if (dir.isDirectory()) {
            snapshotWriter = Executors.newSingleThreadExecutor(new ThreadFactory() {
                    public Thread newThread(Runnable r) {
                        return new Thread(r, TAG);
                    }
                });
            enabled = true;
            Log.i(TAG, "Profiling enabled. Sampling interval ms: "
                  + samplingProfilerMilliseconds);
        } else {
            snapshotWriter = null;
            enabled = true;
            Log.w(TAG, "Profiling setup failed. Could not create " + SNAPSHOT_DIR);
        }
    } else {
        snapshotWriter = null;
        enabled = false;
        Log.i(TAG, "Profiling disabled.");
    }
}

它可能与文档中所述的Honeycomb版本之前的UI呈现的特定行为有关,但我想不出是什么。

http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html

  

在Honeycomb(3.0)之前,活动的状态在暂停之前被保存。碎片是一个重要的新状态,并且足够动态,人们通常希望它们在暂停和停止之间切换。如果您尝试在保存后更改片段状态,则这些类会抛出异常,以避免意外丢失UI状态。然而,在蜂窝状态之前,这种限制性太强,在暂停之前状态会被保存。为了解决这个问题,当在Honeycomb之前的平台上运行时,如果在状态保存和正在停止的活动之间更改片段,则不会抛出异常。这意味着,在某些情况下,如果活动从上次保存的状态恢复,则可能是用户上次查看之前的快照。

1 个答案:

答案 0 :(得分:1)

我发现正在导入项目的支持库v4和v7不支持方法ArrayAdapter<> :: addAll(),这使应用程序崩溃。

这个问题与此问题有关,所提出的解决方案适合解决我的问题:

ListViews - how to use ArrayAdapter.addAll() function before API 11?

因此,解决方案是实现我自己的ArrayAdapter类版本,以便之前的Honeycomb版本的Android可以使用它。