当我在选项卡之间快速移动并快速使用ViewPager时,它崩溃了

时间:2018-06-21 09:35:57

标签: android android-fragments

我在应用程序中使用ViewPagerTabs。当我测试该应用并在tabs之间快速移动时,它崩溃了。我有一个Fragment和3个tabs,并且Fragment的内容在每个tab中都有变化。内容是使用API来自Retrofit 2的数据。我也使用FragmentStatePagerAdapter

这是我的Logs

java.lang.IllegalStateException: Fragment MainFragment{423155d0} not attached to Activity
                                                                           at android.support.v4.app.Fragment.getResources(Fragment.java:715)
                                                                           at com.webstore.footballscores.Fragments.MainFragment$4.onResponse(MainFragment.java:393)
                                                                           at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
                                                                           at android.os.Handler.handleCallback(Handler.java:733)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                           at android.os.Looper.loop(Looper.java:146)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5641)
                                                                           at java.lang.reflect.Method.invokeNative(Native Method)
                                                                           at java.lang.reflect.Method.invoke(Method.java:515)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1288)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104)
                                                                           at dalvik.system.NativeStart.main(Native Method)

此行中的错误

    res = getResources();

其余的代码。

 connection.enqueue(new Callback<List<FixturesObject>>() {
        @Override
        public void onResponse(Call<List<FixturesObject>> call, Response<List<FixturesObject>> response) {
            if (!response.isSuccessful()) {
                progressDoalog.dismiss();
                Toast.makeText(getActivity(), "Something went wrong , Please refresh again", Toast.LENGTH_SHORT).show();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeRefreshLayout.setRefreshing(false);
                    }

                }, 4000);
            } else if (response.isSuccessful()) {
                i=1;
                imageView.setVisibility(View.GONE);
                progressDoalog.dismiss();

                    if (isAdded()) {
                 res = getResources();
                String[] teamEngList = res.getStringArray(R.array.team_english);
                String[] teamArabList = res.getStringArray(R.array.team_arabic);
                }

                     if (response.body().get(i).getLeagueId().equals("109")) {

                                for (int j = 0; j < teamEngList.length; j++) {
                                    if (teamEngList[j].equals(response.body().get(i).getMatchAwayteamName())) {
                                        response.body().get(i).setMatchAwayteamName(teamArabList[j]);
                                    } else if (teamEngList[j].equals(response.body().get(i).getMatchHometeamName())) {
                                        response.body().get(i).setMatchHometeamName(teamArabList[j]);
                                    }
                                }
                                spainObject.add(response.body().get(i));
                                listDataChild.put(listDataHeader.get(listDataHeader.size() - 1), spainObject);
                            }

                   adapter.clearData();

                    adapter.addData(listDataHeader, listDataChild);
                   }

如何解决此错误。 谢谢

3 个答案:

答案 0 :(得分:1)

在滑动ViewPager时,将为可见页面创建碎片,并为不可见页面破坏碎片。您的网络请求与该过程无关。当网络请求完成并且相应的片段被销毁时,您正在尝试调用getResources(),但是此调用需要具有上下文。如果片段已被销毁,则片段不再具有上下文,因此会崩溃。

要解决此问题,您需要在致电之前确保上下文可用。试试这个:

if (!isAdded()) return;

res = getResources();
//...

某些文档:https://developer.android.com/reference/android/support/v4/app/Fragment#isAdded()

答案 1 :(得分:1)

出现异常的原因

您使用的是FragmentStatePagerAdapter,因此可以{strong>销毁Fragment中的ViewPager,然后分离see my demo here)。
在每个Fragment中,您运行一个异步任务(使用Retrofit),并在完成时更新UI。
如果您为以前被破坏的片段更新UI,则会得到异常

解决方案

有一些方法可以解决您的问题

  • 取消接收来自异步请求的回调或取消请求。
  • 异步任务完成后,在更新UI之前,请检查片段是否为isDetached
  • 不要破坏您的片段,可以使用setOffscreenPageLimit

根据您的情况,您可以选择3种方式中的1种

答案 2 :(得分:0)

请求完成后,片段已被分离。例如,您可以cancel()致电,而不是等待响应然后扔掉它。

@Override
public void onDestroy() {
    connection.cancel();
    super.onDestroy();
}

请注意,回调仍将被触发,但使用onFailure()而不是onResponse()