ERROR:Unable to instantiate fragment

 

之前看到别人的一个项目,要求如下:找出android机里所有的应用程序,展现在viewpager里的fragment上,当然fragment里展现的是一个应用程序列表,点击每一个item进入对应应用,退出应用返回目录。其中退出的时候出现这个问题。

 

原因:见到fragment里有空构造函数,突发奇想,重写构造函数,直接在构造函数里传值,貌似运行没有问题,但若fragment没有杀死,由不可见到可见的时候,就会出此bug

 

 

解决办法:1 向fragment里传值:

                课本:setArgument(bundle对象)

                        bundle里如果传入对象还要序列化

 

                2 fragment里创建静态的方法,返回对应fragment对象。(数据源同样需要序列化)

                    

    public static AppFragment newInstance(List appInfos) {        Bundle bundle = new Bundle();        bundle.putParcelableArrayList("appInfos", (ArrayList<? extends Parcelable>) appInfos);        AppFragment fragmanet_app = new AppFragment();        fragmanet_app.setArguments(bundle);        return fragmanet_app;    }

                 fragment里要取出传入的值:

        Bundle bundle = this.getArguments();        if (bundle != null) {            appInfos = bundle.getParcelableArrayList("appInfos");        }

                向fragment里传值

        new AppFragment().newInstance(SettingApps)

 

ERROR:commit already called

解决办法:1.全局的  

FragmentManager fragmentManager;

2.每次切换都刷新一遍:

fragmentTransaction = fragmentManager.beginTransaction().setCustomAnimations(        android.R.anim.fade_in, android.R.anim.fade_out);

切换fragment不刷新数据

 public void changeFragment(Fragment to) {        if (currentFragment != to) {            fragmentTransaction = fragmentManager.beginTransaction().setCustomAnimations(                    android.R.anim.fade_in, android.R.anim.fade_out);            // 先判断是否被add过            if (!to.isAdded()) {                // 隐藏当前的fragment                fragmentTransaction.hide(currentFragment).add(R.id.content, to).commit();            } else {                fragmentTransaction.hide(currentFragment).show(to).commit(); //提交            }            currentFragment = to;        }    }

切换fragment,较为完善的方案

private Fragment currentFragment;    public void changeFragment(Fragment to,String fragmentTag) {         fragmentManager = getSupportFragmentManager();        fragmentTransaction = fragmentManager.beginTransaction();        if (to != null && !to.isAdded()&&fragmentManager.findFragmentByTag(fragmentTag)==null) { // 先判断是否被add过            if (currentFragment != null&¤tFragment!=to) {                fragmentTransaction.hide(currentFragment).add(R.id.rl_content_frg, to).commitAllowingStateLoss();            } else {                if (currentFragment==null){                    fragmentTransaction.add(R.id.rl_content_frg, to,fragmentTag).commitAllowingStateLoss();                }            }            currentFragment = to;        } else {            if (currentFragment != null && currentFragment != to) {                fragmentTransaction.hide(currentFragment).show(to).commitAllowingStateLoss(); // 隐藏当前的fragment,显示下一个                currentFragment = to;            }        }        }

fragment不能显示的问题

最近在7.0系统中使用上面的方法,发现fragment不能显示的问题。故思考的几个办法

1.可能add,hide,show等方法在7.0不兼容,因为6.0,4.4可以显示,so使用viewpager代替。这个方法不可取,临发布前更换架构,码农大忌。

2.可能fragment里有耗时操作导致fragment不加载。有这个可能性,但不适用于当前情况。上面代码的逻辑是,显示fragment时,如果fragment已经展示过,就不会初始化了,而是用show将页面展示出来。但bug的情况是,有概率导致切换fragment的时候,3个页面都不展示。而且activty的某个动画也卡死。如果是展示fragment时卡死,至少有个fragment的背景吧。so,这个可能性较低

3.最大的可能性,就是在activty显示fragment的之前,对frament做了一些操作。我的activty在oncreate的时候就已经new了fragment了,展示的时候就show或者add,但我review代码发现,在new之后,展示之前,我调用了eventbus给fragment发消息,刷新数据了。问题就在这里了,我没有展示fragment,但我发消息给fragment让他刷新ui导致,展示的时候概率性加载不出,去掉后测试果不其然。

 

下面提供一个不用fragmentManager.findFragmentByTag,切换fragment的方法:

 public void changeFragment(Fragment to, String fragmentTag) {        if (currentFragment == null) {            //第一次            fragmentManager = getSupportFragmentManager();            fragmentTransaction = fragmentManager.beginTransaction();            fragmentTransaction.add(R.id.rl_content_frg, to);            fragmentTransaction.show(to);            fragmentTransaction.commit();            currentFragment = to;        } else {            fragmentManager = getSupportFragmentManager();            fragmentTransaction = fragmentManager.beginTransaction();            if (to.isAdded()) {                fragmentTransaction.hide(currentFragment);                fragmentTransaction.show(to);                fragmentTransaction.commit();                currentFragment = to;            } else {                fragmentManager = getSupportFragmentManager();                fragmentTransaction = fragmentManager.beginTransaction();                fragmentTransaction.add(R.id.rl_content_frg, to);                fragmentTransaction.hide(currentFragment);                fragmentTransaction.show(to);                fragmentTransaction.commit();                currentFragment = to;            }        }          }

 

 

 

 

 

 

更多相关文章

  1. C语言函数的递归(上)
  2. AndroidStudio快捷键汇总
  3. 【转】Android之AsyncTask的用法
  4. Android(安卓)实现 WheelView
  5. [Android][Memory Leak] InputMethodManager内存泄露现象及解决
  6. Android(安卓)Studio中必须懂的Gradle(一)--参考Gradle的在线文
  7. Android(安卓)JNI 调用 C/C++
  8. Qt on Android(安卓)Episode 5(翻译)
  9. Android(安卓)NDk 开发简易教程

随机推荐

  1. android HorizontalScrollView的简单使用
  2. ROOT android 原理。 基于(zergRush)
  3. Android-6.0之PMS安装APK上篇
  4. Android(安卓)使用自定义Dialog打造Actio
  5. Layout_weight
  6. 深入学习百度地图Android(安卓)SDK v4.0.
  7. 内存3
  8. Android(安卓)proguard.flags
  9. android 自学日记(六) ——SAX解析中换行问
  10. Firmware加载原理分析