with viewpager romandanylyk relex pageindicatorview circleindicator bullets android android-fragments actionbarsherlock android-viewpager android-support-library

android - viewpager - causando un error java.IllegalStateException, Sin actividad, solo cuando navegas hacia Fragment por SEGUNDA vez



me relex circleindicator circleindicator android (8)

¿Puede su error es android.view.InflateException?

si es así, debe inflar el Fragment dinámicamente, no usar el diseño XML.

y, no debe orientar el fragmento definido como Diseño XML a Fragmentar transacción.

Estoy obteniendo un error muy desconcertante que no tengo ni idea de cómo empezar a trabajar.

Tengo una aplicación simple con una actividad, las vistas se implementan con Fragmentos. Uno de los fragmentos tiene una ViewPager dentro de él; así que decidí que quería usar la clase getChildFragmentManager de la biblioteca de soporte v4. También tuve que usar ActionBarSherlock, que causó un problema, ya que no se incluye con la v11 de la biblioteca v4.

Lo arreglé reemplazando la biblioteca de soporte v4 en ABS con la biblioteca v11, y todo compilado y parecía estar funcionando, incluido el ViewPager.

Aquí está la parte extraña:

La primera vez que se abre el fragmento con ViewPager, funciona correctamente; pero en la SEGUNDA vez que se navega, la aplicación falla, dando un inútil rastro de pila. De la depuración, descubrí que el problema era con FragmentManager devuelto por getChildFragmentManager; arroja el error Sin actividad.

¿Alguien tiene alguna idea de lo que podría estar causando esto?

Voy a publicar el código que creas relevante.

Gracias David


Consulte la respuesta de @lopisan:

Uso su solución por mucho tiempo.

¡PERO me imagino que tengo una mejor manera de hacer esto!

Si mChildFragmentManager.mActivity es nulo, configure mChildFragmentManager como nulo. Cuando se realiza el métodoActivityCreated.

@Override void performActivityCreated(Bundle savedInstanceState) { if (getFragmentManagerActivity(mChildFragmentManager) == null) { setChildFragmentManager(this, null); } super.performActivityCreated(savedInstanceState); } public static FragmentActivity getFragmentManagerActivity(FragmentManager fragmentManager) { FragmentManagerImpl fm = (FragmentManagerImpl) fragmentManager; return fm.mActivity; } private static final Field sChildFragmentManagerField; static { /** * BUG : causing a java.IllegalStateException error, No Activity, only * when navigating to Fragment for the SECOND time * http://.com /questions/15207305/getting-the-error-java-lang-illegalstateexception-activity-has-been-destroyed * http://.com/questions/14929907/causing-a-java-illegalstateexception-error-no-activity-only-when-navigating-to */ Field f = null; try { f = Fragment.class.getDeclaredField("mChildFragmentManager"); f.setAccessible(true); } catch (NoSuchFieldException e) { Log.e(TAG, "Error getting mChildFragmentManager field", e); } sChildFragmentManagerField = f; } public static void setChildFragmentManager(Fragment fragment, FragmentManager fragmentManager) { if (sChildFragmentManagerField != null) { try { sChildFragmentManagerField.set(fragment, fragmentManager); } catch (Exception e) { Log.e(TAG, "Error setting mChildFragmentManager field", e); } } }


Esto parece ser un error reportado en

https://code.google.com/p/android/issues/detail?id=42601

La variable

FragmentManagerImpl mChildFragmentManager;

En Fragment.java no está establecido en null en detach. Entonces, la próxima vez que se cargue el fragmento, la variable aún apunta al último padre.

Como se discutió en ese hilo, una solución es reinstalar el Fragmento.

En mi caso, estaba cambiando entre fragmentos en una pestaña de ActionBar. El problemático Fragment ha anidado Fragments y estaba bloqueando la aplicación al volver al Fragment del cargador de archivos. Este es el código de trabajo:

class MainTabsListener implements ActionBar.TabListener { public Fragment fragment; public int TabPosition; public MainTabsListener(Fragment fragment, int tab_position) { this.fragment = fragment; TabPosition = tab_position; } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { CurrentFragment = fragment; CurrentTabSelectedPos = TabPosition; /** * This is a work-around for Issue 42601 * https://code.google.com/p/android/issues/detail?id=42601 * * The method getChildFragmentManager() does not clear up * when the Fragment is detached. */ if( fragment instanceof FileLoaderFragment ){ fragment = reinstatiateFileLoaderFragment(); } ft.replace(R.id.fragment_container, fragment); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(fragment); } }


Estoy atascado con el mismo error al usar el modificador BottomNavigationView y el reemplazo del fragmento que causa el bloqueo de la aplicación. Con la velocidad normal, funcionaba perfectamente bien, si el usuario lo cambiaba rápido solía decir que no funcionaba.

IllegalStateException Sin actividad

en Logs

Antes de tener

fragmentA = new FragmentA(); fragmentB = new FragmentB(); fragmentC = new FragmentC(); mBottomNavigationView.setOnNavigationItemSelectedListener(item -> { switch (item.getItemId()) { case R.id.fragmentA: replaceFragment(fragmentA); case R.id.fragmentB: repalceFragment(fragmentB); case R.id.fragmentC: repalceFragment(fragmentC); } };

Creo que esta pre-creación de fragmento y usarlos fue para reemplazar está creando el problema, ahora lo hice para volver a crear cada vez. Empezó a funcionar bien

mBottomNavigationView.setOnNavigationItemSelectedListener(item -> { switch (item.getItemId()) { case R.id.fragmentA: fragment = new FragmentA(); replaceFragment(fragment); case R.id.fragmentB: fragment = new FragmentB(); repalceFragment(fragment); case R.id.fragmentC: fragment = new FragmentC(); repalceFragment(fragment); } }; public void repalceFragment(Fragment fragment) { if (!this.isFinishing()) { if (!fragment.isAdded()) { if (!this.mDisplayedFragment.isRemoving()) { getFragmentManager().beginTransaction().replace(R.id.layout_fragment_container, fragment).commit(); this.mDisplayedFragment = fragment; } } } }

Espero que sea útil para algunos, hice demasiada codificación defensiva, pero resolvió mi problema de conmutación rápida de fragmentos



Seguí el enlace en jeremyvillalobos respuesta (que fue muy útil) que me llevó a esta solución .

public class CustomFragment extends Fragment { private static final Field sChildFragmentManagerField; static { Field f = null; try { f = Fragment.class.getDeclaredField("mChildFragmentManager"); f.setAccessible(true); } catch (NoSuchFieldException e) { Log.e(LOGTAG, "Error getting mChildFragmentManager field", e); } sChildFragmentManagerField = f; } @Override public void onDetach() { super.onDetach(); if (sChildFragmentManagerField != null) { try { sChildFragmentManagerField.set(this, null); } catch (Exception e) { Log.e(LOGTAG, "Error setting mChildFragmentManager field", e); } } } ... }

Funciona bien para mí, sin la necesidad de reinstalar el fragmento.


Tengo el mismo problema.

En una actividad, tengo 3 botones para cambiar fragmento con transaction.replace (...)

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.layout_tablet_paneau, mLigneMessageFragment);

Uno de este fragmento contiene una ViewPage con un FragmentPagerAdapter personalizado. Por lo tanto, debo hacer getChildFragmentManager (), para dejar de lado los Fragmentos anidados.

el constructor está aquí:

public LignePagerAdapter(Fragment ligneMessageTabletFragment) { super(ligneMessageTabletFragment.getChildFragmentManager()); }

Así que tengo el mismo error: la primera muestra de este fragmento se escribe, pero cuando muestro otro fragmento y vuelvo a este, obtengo esta excepción:

02-26 11:57:50.798: D/ACRA(776): Wait for Toast + worker ended. Kill Application ? true 02-26 11:57:50.798: E/AndroidRuntime(776): FATAL EXCEPTION: main 02-26 11:57:50.798: E/AndroidRuntime(776): java.lang.IllegalStateException: No activity 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1861) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1474) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.os.Handler.handleCallback(Handler.java:587) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.os.Handler.dispatchMessage(Handler.java:92) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.os.Looper.loop(Looper.java:132) 02-26 11:57:50.798: E/AndroidRuntime(776): at android.app.ActivityThread.main(ActivityThread.java:4126) 02-26 11:57:50.798: E/AndroidRuntime(776): at java.lang.reflect.Method.invokeNative(Native Method) 02-26 11:57:50.798: E/AndroidRuntime(776): at java.lang.reflect.Method.invoke(Method.java:491) 02-26 11:57:50.798: E/AndroidRuntime(776): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) 02-26 11:57:50.798: E/AndroidRuntime(776): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) 02-26 11:57:50.798: E/AndroidRuntime(776): at dalvik.system.NativeStart.main(Native Method) 02-26 11:57:52.818: I/dalvikvm(776): threadid=4: reacting to signal 3 02-26 11:57:52.818: I/dalvikvm(776): Wrote stack traces to ''/data/anr/traces.txt''

Entonces, en lugar de poner la misma instancia de fragmento, puedo volver a crear esto para que solucione el problema, pero no parezco eficiente.

transaction.replace(R.id.layout_tablet_paneau, LigneMessageTabletFragment.newInstance());


lamentablemente, es un error de soporte v4, sigue ahí :(

Cuando eliges otro Fragmento a través del Cajón de Navegación u otra cosa similar, el fragmento que tiene subfragmentos se separa. Por lo tanto, esos subfragmentos ''fragmentManager (getChildFragmentManager ()) ya no existen. mientras esos fragmentos regresan, ocurrió un error. ¡Bomba!

Obviamente, el soporte v4 debería limpiar mChildFragmentManager en onDetach (), pero no fue así, por lo que debemos depender de nosotros mismos. como seguir códigos en el fragmento que tiene subfragmentos:

@Override public void onDetach() { try { Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager"); childFragmentManager.setAccessible(true); childFragmentManager.set(this, null); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } super.onDetach(); }

Todo estará bien, tenga un buen día :)