11

Il test OnBackPressed() genera NPE quando ho aggiunto una transizione personalizzata . Va bene senza le transizioni personalizzate. Perché?Unit test NPE, quando aggiungo le transizioni personalizzate del frammento

QUESTO NPE SUCCEDE SOLO NELLA PROVA DELL'UNITÀ, NON L'APP.

class MyActivity { 
    @Override 
    public void onBackPressed() { 
     ....... 
     super.onBackPressed(); 
    } 

    private void putFragment(Fragment fragment) { 
      String tag = fragment.getClass().getName(); 

      FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 

      // TEST FAILED IF I ADD THE FOLLOWING LINE 
      transaction.setCustomAnimations(
        R.anim.slide_in_left_fade_in, 
        R.anim.fade_out_short_anim_time, 
        R.anim.fade_in_short_anim_time, 
        R.anim.slide_out_right_fade_out); 

      transaction.replace(R.id.ub__add_profiles_content, fragment, tag); 
      transaction.addToBackStack(tag); 
      transaction.commit(); 
    } 
} 

class MyActivityTest extends RiderRobolectricBase { 

    @Test 
    public void onBackPressed() { 
     putFragment(someFragment); 

     mMyActivity.onBackPressed(); 
    } 
} 

Eccezione:

java.lang.NullPointerException 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126) 
    at android.support.v4.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1304) 
    at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:909) 
    at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1625) 
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:561) 
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:166) 
    at MyActivity.onBackPressed(MyActivity.java:28) 
+0

Quale codice è nel vostro onbackpressed di MyActivity? –

+0

Si prega di postare il layout per fade_in_short_anim_time e slide_out_right_fade_out, almeno quelli xml. –

risposta

1

Onbackpress si sta invertendo le fasi precedenti dall'interno del backstack. Il primo è quello di rimuovere il frammento esistente. Il frammento viene rimosso dall'attività e
non si sta conservando un'istanza di questo frammento.

java.lang.NullPointerException 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126) 
    at android.support.v4.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1304) 
    at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:909) 
    at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1625) 
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:561) 
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:166) 
    at MyActivity.onBackPressed(MyActivity.java:28) 

Hai chiamato putFragment(someFragment).
Quindi quando vai a chiamare setCustomAnimations. La vista precedente non viene salvata per essere utilizzata nella transizione.

// TEST FAILED IF I ADD THE FOLLOWING LINE 
transaction.setCustomAnimations(
    R.anim.slide_in_left_fade_in, 
    R.anim.fade_out_short_anim_time, 
    R.anim.fade_in_short_anim_time, 
    R.anim.slide_out_right_fade_out); 

È possibile mantenere l'istanza nel metodo OnCreate del frammento:

setRetainInstance(true); 

Per quanto riguarda questo lavoro nella vostra applicazione, non riesco a vedere il codice all'interno del vostro evento onBackPressed della vostra attività.

0

Il codice sembra corretto. Sospetto che non sia possibile chiamare addToBackStack() dopo aver utilizzato replace() a causa della chiamata setCustomAnimations. Quindi, per un test rapido, è sufficiente rimuovere la chiamata a addToBackStack.

Normalmente è possibile chiamare addToBackStack() dopo replace(). Lo faccio molte volte.

Fatemi sapere i vostri risultati ...