我在应用程序中使用ViewPager
和Tabs
。当我测试该应用并在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);
}
如何解决此错误。 谢谢
答案 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,则会得到异常
有一些方法可以解决您的问题
根据您的情况,您可以选择3种方式中的1种
答案 2 :(得分:0)
请求完成后,片段已被分离。例如,您可以cancel()致电,而不是等待响应然后扔掉它。
@Override
public void onDestroy() {
connection.cancel();
super.onDestroy();
}
请注意,回调仍将被触发,但使用onFailure()
而不是onResponse()