3

我有一个应用程序,它通过片段容器(在选项卡上)打开几个片段(实际上是 3 个),第一个片段使用 AsyncTask 将提要下载到应用程序中。屏幕旋转时会出现问题 - 应用程序崩溃。我通过将 PostExecute 中的数据加载到私有静态变量中来临时处理这个问题,但是当用户第一次进入应用程序时,仍然会出现这个问题。

这似乎是一个非常普遍或猖獗的问题,但我无法在这里找到彻底的解决方案。我确实理解这是因为屏幕旋转导致配置更改,因为 AsyncTask 在与 UI 线程并行的线程上运行。在这个阶段我确实避免使用 Java 线程/执行程序/执行程序服务,因为 AsyncTask 中似乎有一个现成的工具

我无法中断进程以成功重新启动活动或片段并丢弃初始的后续 AsyncTask 调用..

换句话说,当屏幕旋转等配置发生连续变化时,如何销毁片段中的 AsyncTask。您的帮助将不胜感激。

public class MolyListFragment extends Fragment {
public final static String MOLY_ARTICLE_DATA = "No Details";
private static final String TAG = "MOLY";
private static ArrayList<MolyPg> mMolyPgs = null;

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

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (mMolyPgs == null) {
        new MolyLoadTask().execute(getResources().getString(R.string.mly_feed));
    }
    else
        displayMlicles (mMolyPgs); //this displays the arrayList out of static mMolyPgs
}


private class MolyLoadTask extends AsyncTask<String, Void, ArrayList<MolyPg>> {
@Override
protected ArrayList<MolyPg> doInBackground(String... urls) {
        String myUrl = urls[0];
        ArrayList<MolyPg> myMlPgs = null;
    try {
            myMlPgs =  loadXmlFromNetwork(myUrl);
    } catch (MalformedURLException e) {
        Log.d(TAG, "MalformedURLException", e);
    } catch (IOException e) {
            getResources().getString(R.string.connection_error);
    } catch (XmlPullParserException e) {
            getResources().getString(R.string.xml_error);
    }

    return myMlPgs;
    }


    @Override
    protected void onPostExecute(ArrayList<MolyPg> result) {
        super.onPostExecute(result);

        Do some acrobatics here
    }
........    
    }
}
4

3 回答 3

4

您可以使用多种解决方案,但它们都有一个共同的主题……您不应该将长期运行的操作如此紧密地直接绑定到您的用户界面类。

如果我要提出一个建议,通常有两种可能效果很好:

  • 实现您AsyncTask的自定义内部AsyncTaskLoader,您可以在每次Fragment重新启动时连接到该自定义以检索数据或等待它返回。您需要实现许多回调方法,因此您需要参考文档(链接)。您可能还想查看源代码CursorLoader以获取另一个实现示例AsyncTaskLoader
  • 在您的应用程序中创建一个“数据” Fragment,其唯一目的是管理您的后台任务并在可用时提供信息。这个片段将没有 UI 组件(即不要覆盖onCreateView()),您将调用setRetainInstance()因此FragmentManager只保留一个。当您添加带有常量标签值的片段时,您 UI 中的所有其他组件都可以通过 轻松找到它FragmentManager以检索数据。有关这方面的更多信息,请参阅文档部分添加没有 UI 的片段
于 2012-11-27T21:14:02.267 回答
1

如果您使用的是片段,则应该使用 Loaders。检查文档:

http://developer.android.com/reference/android/app/LoaderManager.html

该片段将找到任何以前创建的加载器并“重新连接”,因此您可以从中获取结果。

也有一些方法可以“重新连接”AsyncTasks,但最好只使用 Loaders。

于 2012-11-27T20:30:53.117 回答
1

您可以使用setRetainInstance(),但是正如文档所说,这只能与不在后台堆栈中的片段一起使用

于 2012-11-27T21:03:20.060 回答