【问题标题】:Showing fragment after activity fetches data在活动获取数据后显示片段
【发布时间】:2015-01-30 07:50:47
【问题描述】:

我正在我的活动中获取多个片段所需的数据。返回数据后,我创建片段。我是通过 AsyncTask 执行此操作的,但如果在屏幕旋转或应用程序后台运行后返回数据,则会导致偶尔崩溃。

我阅读并认为解决方案是使用 AsyncTaskLoader。假设如果您的活动消失了,它不会回调,因此应该解决这些错误。但是现在每次都会崩溃,因为“无法在 onLoadFinished 内执行此操作(添加片段)”。

我应该如何处理这个问题?我不希望我的每个片段都必须获取数据,因此似乎 Activity 是放置代码的正确位置。

谢谢!

编辑 1

这是相关代码。我认为问题不在于代码本身,而在于我的整个方法。例外很明显,我不应该创建片段。我只是不知道该怎么做。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getSupportLoaderManager().initLoader(BREWERY_LOADER, null, this).forceLoad();
}

//================================================================================
// Loader handlers
//================================================================================

@Override
public Loader<Brewery> onCreateLoader(int id, Bundle args) {
    int breweryId = getIntent().getIntExtra(EXTRA_BREWERY_ID, -1);
    return new BreweryLoader(this, breweryId);
}

@Override
public void onLoadFinished(Loader<Brewery> loader, Brewery data) {
    if (data != null) {
        onBreweryReceived(data);
    } else {
        onBreweryError();
    }
}

@Override
public void onLoaderReset(Loader<Brewery> loader) {

}

...

protected void onBreweryReceived(Brewery brewery) {
    ...
    createFragments();
}

...

protected void createFragments() {
    FragmentManager fm = getSupportFragmentManager();

    //beers fragment
    mBeersFragment = (BreweryBeersFragment)fm.findFragmentById(R.id.beersFragmentContainer);

    if (mBeersFragment == null) {
        mBeersFragment = new BreweryBeersFragment();
        fm.beginTransaction()
                .add(R.id.beersFragmentContainer, mBeersFragment)
                .commit();

        Bundle beersBundle = new Bundle();
        beersBundle.putInt(BreweryBeersFragment.EXTRA_BREWERY_ID, mBrewery.getId());
        mBeersFragment.setArguments(beersBundle);
    }
}

编辑 2

我的新策略是使用带有 ResultReceiver 的 IntentService。我在 onPause 中取消了回调,因此不存在我的活动在不应该被击中的危险。这感觉比必要的要笨重得多,但是 AsyncTask 和 AsyncTaskLoader 似乎都没有我需要的一切。在这些回调方法中创建片段似乎也不会对 Android 造成困扰。

【问题讨论】:

  • 请显示一些代码,猜猜你可能不是从 UI 线程启动 AsyncTaskLoader。

标签: android android-fragments android-asynctask asynctaskloader


【解决方案1】:

MVC (Model -- View -- Controller) 的角度来看,Activity 和它的片段是 Controller,而 Model 应该负责加载数据。至于View,它是由layout xml定义的,你可以定义自定义的View类,但通常你不会。

所以创建一个 Model 类。 模型负责必须在屏幕转动后幸存下来的内容。 (很可能,它将是一个静态单例;请注意,Android 可以终止并重新创建进程,因此单例可能会设置为 null。)请注意 Activities use Bundles to send data to themselves in the future

【讨论】:

  • 我将数据保存在单例模型中。不过我的问题是我需要先在我的活动中获取数据,以便我的两个片段都可以访问它。这是让我难过的部分——如何延迟创建它们,直到获取必要的数据。
  • 您的活动将设置回调并调用theModelSingleton.startFetchingData()。在数据获取函数调用回调后,您将能够创建片段或(更好地)更改它们以反映获取的数据。不要在 Fragments 中放入过多的应用逻辑,它们是 Controllers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-12
  • 2015-06-22
  • 1970-01-01
相关资源
最近更新 更多