1、问题引入

在Fragment中执行一段耗时任务,在任务未结束的时候,重建Activity就会导致getActivity()null,所有用到getActivity()的地方都会引起空指针异常,如果使用了getResources()方法,就会导致Fragment not attached to Activity

为了重现这一异常,我们编写如下代码:

  • FirstFragment.java
public class FirstFragment extends Fragment implements View.OnClickListener {private TextView tvMsg;private Button btnStartTask, btnRecreate;private static final String TAG = "FirstFragment";public FirstFragment() {// Required empty public constructor}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_first, container, false);tvMsg = (TextView) view.findViewById(R.id.tvMsg);btnStartTask = (Button) view.findViewById(R.id.btnStartTask);btnRecreate = (Button) view.findViewById(R.id.btnRecreate);btnStartTask.setOnClickListener(this);btnRecreate.setOnClickListener(this);return view;}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btnStartTask:// 模拟一个耗时任务new AsyncTask<Void, Void, Void>() {@Overrideprotected Void doInBackground(Void... params) {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return null;}@Overrideprotected void onPostExecute(Void aVoid) {super.onPostExecute(aVoid);Log.d(TAG, "getActivity = " + getActivity());tvMsg.setText(getResources().getString(R.string.app_name));}}.execute();break;case R.id.btnRecreate:// 重新创建MainActivitygetActivity().recreate();break;}}
}
  • SecondFragment.java
public class SecondFragment extends Fragment {public SecondFragment() {// Required empty public constructor}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_second, container, false);}
}
  • fragment_first.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="cc.duduhuo.fragmentattachdemo.fragment.FirstFragment"><TextViewandroid:id="@+id/tvMsg"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="The First Fragment" /><Buttonandroid:id="@+id/btnStartTask"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="耗时任务" /><Buttonandroid:id="@+id/btnRecreate"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="重建Activity" />
</LinearLayout>
  • fragment_second.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="cc.duduhuo.fragmentattachdemo.fragment.SecondFragment"><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:text="The Second Fragment" /></FrameLayout>
  • MainActivity.java
public class MainActivity extends FragmentActivity {private ViewPager mViewPager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mViewPager = (ViewPager) this.findViewById(R.id.pager);initial();}private void initial() {List<Fragment> fragmentList = new ArrayList<>();List<String> titleList = new ArrayList<>();fragmentList.add(new FirstFragment());fragmentList.add(new SecondFragment());titleList.add("First");titleList.add("Second");MyFragmentPageAdapter adapter = new MyFragmentPageAdapter(getSupportFragmentManager(), fragmentList, titleList);mViewPager.setAdapter(adapter);}private class MyFragmentPageAdapter extends FragmentPagerAdapter {private List<Fragment> fragmentList;private List<String> titleList;public MyFragmentPageAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> titleList) {super(fm);this.fragmentList = fragmentList;this.titleList = titleList;}@Overridepublic Fragment getItem(int position) {return (fragmentList == null || fragmentList.size() == 0) ? null : fragmentList.get(position);}@Overridepublic CharSequence getPageTitle(int position) {return (titleList.size() > position) ? titleList.get(position) : "";}@Overridepublic int getCount() {return fragmentList == null ? 0 : fragmentList.size();}}
}
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="cc.duduhuo.fragmentattachdemo.MainActivity"><android.support.v4.view.ViewPagerandroid:id="@+id/pager"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v4.view.PagerTabStripandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="top" /></android.support.v4.view.ViewPager>
</LinearLayout>

当点击FirstFragment里面的“耗时任务”按钮时,会执行一个2000ms的任务(上面的代码是用休眠2000ms代替一个耗时任务)。如果点过之后静静等待2000ms,上面的TextView的文本就会变成FragmentAttachDemo,并不会报出任何异常。但是当我们点击“耗时任务”按钮之后,在它还未执行完毕时,点击下面的“重建ACTIVITY”按钮,很快程序就会崩溃。

控制台打印出来的信息如下图所示:

错误信息

除了点击“重建ACTIVITY”按钮之外,点击“耗时任务”按钮之后立即旋转手机屏幕也会导致此异常,因为默认情况下屏幕旋转也会重建Activity。

2、问题解决

FirstFragmentonPostExecute()方法中的

tvMsg.setText(getResources().getString(R.string.app_name));

改为

if (isAdded()) {tvMsg.setText(getResources().getString(R.string.app_name));
}

isAdded()方法可以判断当前的Fragment是否已经添加到Activity中,只有当Fragment已经添加到Activity中时才执行getResources()等方法。

另请参考:http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity

当然,以上只是引起该异常的一个例子,并不能解决所有“Fragment not attached to Activity”的问题。

3、代码下载

Demo代码下载

转载自:https://www.jianshu.com/p/7986206aa9d4

Fragment not attached to Activity 解决方案相关推荐

  1. Fragment not attached to Activity

    BUG 在Fragment中执行一段耗时任务,在任务未结束的时候,重建Activity就会导致getActivity()为null,所有用到getActivity()的地方都会引起空指针异常,如果使用 ...

  2. [Android Pro] java.lang.IllegalStateException: Fragment(XXFragment) not attached to Activity异常

    [Android Pro] java.lang.IllegalStateException: Fragment(XXFragment) not attached to Activity异常 参考文章: ...

  3. Fragment XXXXXX{xxxxxxxxx} not attached to Activity

    Monkey跑出如下异常.导致Settings Crash E AndroidRuntime: at android.app.Fragment.getResources(Fragment.java:8 ...

  4. 报错:Fragment not attached to an activity

    错误描述 在Fragment里面进行网络请求,在请求未结束时跳转到其他页面,再从其他页面跳回来,编译器报如下错误: E/AndroidRuntime: FATAL EXCEPTION: mainPro ...

  5. 安卓APP_ Fragment(2)—— Activity与Fragment的通信

    摘自:安卓APP_ Fragment(2)-- Activity与Fragment的通信 作者:丶PURSUING 发布时间: 2021-04-16 17:23:44 网址:https://blog. ...

  6. Android系列之Fragment(一)----Fragment加载到Activity当中

    参考文章出处: 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3978989.html 前言 A ...

  7. Android如何让Fragment加载到Activity中

    Android上的界面展示都是通过Activity实现的,Activity实在是太常用了.但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了,因为平板的屏幕非常大, ...

  8. Android Fragment跳转到Activity的方法

    一开始我直接按照Activity页面之间跳转的方法进行的跳转,就是在xml文件中给相应的组件onClick android:onClick="to_search" 在网上查询到的好 ...

  9. Android Fragment异常:java.lang.IllegalStateException: Fragment XXXFragment not attached to Activity

    出现该异常,是因为Fragment的还没有Attach到Activity时,调用了如getResource()等需要上下文Context的函数.解决方法,就是等将调用的代码写在OnStart()中.

最新文章

  1. 【廖雪峰python入门笔记】列表生成式
  2. 情绪调节的自适应_心理健康系列 | 大学生常见情绪问题及调试方法
  3. layoutSubviews何时被调用
  4. google 浏览器清除缓存
  5. matlab如何创建callback函数_如何学好MATLAB GUI
  6. spring配置主库从库_spring下的数据库主从分离(下)
  7. matlab中欠定方程组超定方程组_《数值天气预报》:球坐标系中的基本方程组
  8. java递归分苹果_递归较难题——分苹果问题
  9. python2/3 模块gmpy2在linux下安装
  10. 深入理解基本包装类型
  11. 【深度语义匹配模型】实践篇:语义匹配在贝壳找房智能客服中的应用
  12. Google手机移动网站适配(双向注释)
  13. ios开发之验证你的服务器ATS是否PASS
  14. Django  403 CSRF token missing or incorrect.
  15. 自动布局和view 设置frame同时有效
  16. django mysql debug_django mysql db 日志无输出
  17. 要用计算机处理频谱,妙用Adobe Audition 系列教程(二):频谱分析仪 | 小众声学...
  18. .Net框架搭建之1、SQL Server EF MVC简单三层框架
  19. android内窥镜安装软件,DEPSTECH内窥镜app
  20. 什么是DTC?为什么国内外如此火爆

热门文章

  1. 计算机小写换大写函数,在Excel中将金额从小写转换为大写以在Excel RMB中自动将金额大写的三种方法...
  2. lg显示器工厂模式怎么进入_aoc显示器如何进入工程模式
  3. 幸福的烦恼—当本地化客户端遇上本地化服务器
  4. 献结程序员的一个故事——管道的故事
  5. Windows提权方法
  6. Bugku之Flask_FileUpload
  7. 蚂蚁金服 ant design 中下载axure 菜单组件库
  8. keytool生成证书的方法
  9. 我与Saturn有个约会
  10. 127.0.0.1、0.0.0.0和本机IP地址的区别和使用