2017-02-05 10 views
0

Когда я повернуть мое устройство во время отображения DialogFragment, мое приложение аварии:App показывает DialogFragment падает после поворота

E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.myapp, PID: 27909 
java.lang.RuntimeException: Unable to destroy activity {com.myapp/com.myapp.FileListActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4203) 
    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4221) 
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4495) 
    at android.app.ActivityThread.-wrap19(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1483) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6126) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
    Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493) 
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511) 
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638) 
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:617) 
    at android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:201) 
    at android.support.v4.app.DialogFragment.dismiss(DialogFragment.java:167) 
    at com.myapp.ActionsDialogFragment.onDestroy(ActionsDialogFragment.java:127) 
    at android.support.v4.app.Fragment.performDestroy(Fragment.java:2202) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1196) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1234) 
    at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:2083) 
    at android.support.v4.app.FragmentController.dispatchDestroy(FragmentController.java:244) 
    at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:368) 
    at android.support.v7.app.AppCompatActivity.onDestroy(AppCompatActivity.java:203) 
    at com.myapp.FileListActivity.onDestroy(FileListActivity.java:1106) 
    at android.app.Activity.performDestroy(Activity.java:6881) 
    at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1154) 
    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4190) 
    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4221)  
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4495)  
    at android.app.ActivityThread.-wrap19(ActivityThread.java)  
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1483)  
    at android.os.Handler.dispatchMessage(Handler.java:102)  
    at android.os.Looper.loop(Looper.java:154)  
    at android.app.ActivityThread.main(ActivityThread.java:6126)  
    at java.lang.reflect.Method.invoke(Native Method)  
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)  
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)  

Это мой DialogFragment:

public class ActionsDialogFragment extends DialogFragment { 

    public interface ActionsDialogListener { 
     void onActionSelected(DialogFragment dialog, int position); 
    } 

    AlertDialog dialog; 
    ActionsDialogListener mListener; 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     try { 
      mListener = (ActionsDialogListener) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
        + " must implement ActionsDialogListener"); 
     } 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
     dialog = builder.create(); 
     return dialog; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.actions_dialog, container, false); 

     CustomListAdapter cla; 
     cla = new CustomListAdapter(getActivity()); 
     ListView list = (ListView) view.findViewById(R.id.listViewActions); 
     final AlertDialog finalDialog = dialog; 
     list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       mListener.onActionSelected((DialogFragment) getParentFragment(), position); 
       Log.d(FileListActivity.TAG, "Dismissing dialog"); 
//    ActionsDialogFragment.this.dismiss(); 
       finalDialog.dismiss(); 
      } 
     }); 
     list.setAdapter(cla); 
     dialog.setView(view); 
     return view; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(FileListActivity.TAG, "ActionDialogFragment onDestroy()"); 
     dismiss(); 
//  dialog.dismiss(); 
    } 

    class CustomListAdapter extends ArrayAdapter<String> { 
    ... 
    } 

} 

Ошибка говорит: «Не удается выполнить это действие после onSaveInstanceState ". Но я не знаю, где хранится InstanceState. Для меня нормально отменить диалог и воссоздать его после поворота.

Любая идея, что происходит не так?

EDIT:

Мой DialogFragment создается в основной деятельности, как, что:

void showActionsDialog() { 
    actionsDialog = new ActionsDialogFragment(); 
    actionsDialog.show(getSupportFragmentManager(), "ActionsDialogFragment"); 
} 

EDIT 2:

Только в случае, если это важно. Это моя основным видом деятельности в onDestroy() метод:

public void onDestroy() { 
    super.onDestroy(); 
    Log.d(TAG, "FileListActivity onDestroy()"); 
    if (exifReadingDialog != null) { exifReadingDialog.dismiss(); } 
    dataFragment.mRetainedCache = mMemoryCache; 
    dataFragment.setData(mediaFolder); 
} 

EDIT 3:

Некоторые дополнительные мысли: Многие люди здесь на StackOverflow говорят, что вы должны использовать либо onCreateDialog или onCreateView в DialogFragment. Возможно, это моя проблема. Но если я удалю onCreateDialog и переменную dialog, увольнение больше не будет работать. До сих пор я использую это решение: Cannot get DialogFragment to dismiss programatically (только для отклонения диалогового окна, но сбой при вращении)

ответ

0

Тем временем я перепробовала много вещей. Я изменил свой ActionsDialogFragment, чтобы больше походить на this tutorial.

Но я думаю, что настоящая ошибка была в моем обычном ListAdapter. Я изменил эту часть

public @NonNull View getView(int position, View view, @NonNull ViewGroup parent) { 
    LayoutInflater inflater = getLayoutInflater(null); 

в

public @NonNull View getView(int position, View view, @NonNull ViewGroup parent) { 
    LayoutInflater inflater = ((Activity)context).getLayoutInflater(); 

Теперь я могу уволить DialogFragment по простой dismiss(); и приложение не врезаться больше после поворота.

Так что я должен был разместить полный класс в своем вопросе. Спасибо за вашу помощь!

1

Я думаю, что проблема си, что OnDestroy называет сделку Fragment фиксации на материнской деятельности, и это не может быть сделано после того, как onSavedInstance имеет был вызван, и это делается до onDestroy. Вам действительно нужно убрать onDestroy() ??

+0

Если я не отклоняю, я получаю эту ошибку: 'E/WindowManager: android.view.WindowLeaked: Activity com.myApp.FileListActivity имеет просочившееся окно DecorView @ 2b05e78 [], которое изначально было добавлено здесь – MaxGyver

+0

Тогда сделайте это onPause, а не onDestroy – FrankMonza

+0

Вы имеете в виду 'public void onPause() {super.onPause(); dismissAllowingStateLoss(); } 'в' ActionsDialogFragment'? Такая же ошибка! – MaxGyver

1

Вы получаете исключение «Исчезнутое окно», потому что Alert dialog работает, пока ваша деятельность уничтожена. Вы должны отклонить диалог, когда деятельность уничтожается

попробовать это:

@Override 
protected void onDestroy() { 
    try { 
     if (dialog!= null && dialog.isShowing()) { 
      dialog.dismiss(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    super.onDestroy(); 
} 

Также в вашем setOnItemClickListener закрыть диалоговое окно первого

list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

      if (finalDialog != null && finalDialog.isShowing()) { 
        finalDialog.dismiss(); 
      } 
      mListener.onActionSelected((DialogFragment) getParentFragment(), position); 
      Log.d(FileListActivity.TAG, "Dismissing dialog"); 
    //  ActionsDialogFragment.this.dismiss(); 
     } 
    }); 
+0

В моем коде отсутствует 'FragmentTransaction.commit()'. Я добавил функцию, создающую свой DialogFragment, на мой вопрос. Я попытался изменить 'reject();' на 'rejectAllowingStateLoss();' но безуспешно. Если я использую ваш пример кода вместо 'actionsDialog.show (getSupportFragmentManager(),« ActionsDialogFragment »);' из моего кода приложение по-прежнему выходит из строя с аналогичной ошибкой: 'java.lang.RuntimeException: не удается уничтожить действие {com. myApp/com.myApp.FileListActivity}: java.lang.IllegalStateException: активность была уничтожена'. – MaxGyver

+0

проверить отредактированный ответ – rafsanahmad007

+0

Я пробовал это (это почти то же самое, что я пытался раньше), и он дает мне ошибку из моего последнего комментария. Я думаю, проблема в том, что мой 'ActionsDialogFragment' отклоняется в методе' onDestroy() '. Если я удалю 'rejectAllowingStateLoss();', я получаю сообщение об ошибке из комментария к ответу FrankMonza («Activity has leak the window»). – MaxGyver