【问题标题】:Switching fragments while asnycTask is running causes error在 asnycTask 运行时切换片段会导致错误
【发布时间】:2014-09-01 06:59:27
【问题描述】:

我的应用程序的行为在一个容器活动上运行,上面有不同的片段。现在在这些片段中,我执行异步任务以从 Web API 检索数据。我遇到了一个问题,当异步任务尚未完成时,我尝试切换片段,它会导致错误。我有点理解错误的逻辑,因为任务完成后,它会在任务完成后转到 onPostExecute() 执行其他 UI 相关功能,执行它的片段现在已经消失,现在有一个新片段。有没有办法解决这个问题?根据研究,我已经为片段包含了 setRetainInstance(true),但错误仍然存​​在。

这是我切换片段:

Fragment fragment = new Fragment();
fragment.setRetainInstance(true); 
fragment = new MyFragment();
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                       .replace(R.id.main_container, fragment)
                       .commit();

这是我的 asyncTask 的示例

private class SomeTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... id) {
        // TODO Auto-generated method stub
        //do some logic here on getting data from web api

        return null;
    }

    protected void onPostExecute(Void x) {
        //do some UI functions here
    }

 }

我通常在我的参数上使用 void,因为我经常使用类/全局变量,所以我可以在我的类中的任何地方访问它们。

更新:

Logcat 错误:

09-01 14:50:33.764: E/AndroidRuntime(617): FATAL EXCEPTION: AsyncTask #2
09-01 14:50:33.764: E/AndroidRuntime(617): java.lang.RuntimeException: An error occured while executing doInBackground()
09-01 14:50:33.764: E/AndroidRuntime(617):  at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-01 14:50:33.764: E/AndroidRuntime(617):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.lang.Thread.run(Thread.java:856)
09-01 14:50:33.764: E/AndroidRuntime(617): Caused by: java.lang.NullPointerException
09-01 14:50:33.764: E/AndroidRuntime(617):  at com.nurserversity.com.Helpers.ApiHelper.<init>(ApiHelper.java:49)
09-01 14:50:33.764: E/AndroidRuntime(617):  at com.nurserversity.com.DashboardHome$GetProductBundlesTask.doInBackground(DashboardHome.java:115)
09-01 14:50:33.764: E/AndroidRuntime(617):  at com.nurserversity.com.DashboardHome$GetProductBundlesTask.doInBackground(DashboardHome.java:1)
09-01 14:50:33.764: E/AndroidRuntime(617):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-01 14:50:33.764: E/AndroidRuntime(617):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-01 14:50:33.764: E/AndroidRuntime(617):  ... 5 more

【问题讨论】:

  • 发布您的 logcat 错误以及一些足够的代码。您没有显示必要的部分
  • 查看我更新的帖子。
  • 显示你的DashboardHome$GetProductBundlesTask.doInBackground(DashboardHome.java:115)的第115行代码

标签: android android-fragments android-asynctask


【解决方案1】:

我能想到两个选择:

  1. 切换片段时中止 AsyncTask。

  2. onPostExecute() 中,以稍后再次显示片段时可以检索的方式存储数据。例如,您可以将数据放入 SQLite 数据库或 SharedPreferences。

【讨论】:

  • 嗯,这可能是一个不错的选择。如何中止运行 asyncTasks?我正在考虑在切换片段时中止每个正在运行的异步任务。
【解决方案2】:

我有同样的错误。当我们移出片段时,我只是停止了异步任务。

@Override
    public void onStop() {
        super.onStop();
        if(postToServerAsyncTask!=null && postToServerAsyncTask.getStatus()==Status.RUNNING){
            postToServerAsyncTask.cancel(true);
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-02
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    相关资源
    最近更新 更多