5

Tôi có Trình xử lý hiển thị Hộp thoại khi nhận được một thông báo cụ thể. Điều này thường làm việc, nhưng nếu các mảnh đã được lưu, tôi nhận được lỗi sau:Cách hiển thị DialogFragment từ Bộ xử lý

E/AndroidRuntime(3898): FATAL EXCEPTION: main E/AndroidRuntime(3898): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState E/AndroidRuntime(3898): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) E/AndroidRuntime(3898): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime(3898): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) E/AndroidRuntime(3898): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) E/AndroidRuntime(3898): at android.support.v4.app.DialogFragment.show(DialogFragment.java:123) E/AndroidRuntime(3898): at com.malauzai.app.BaseActivity$2.handleMessage(BaseActivity.java:72) E/AndroidRuntime(3898): at android.os.Handler.dispatchMessage(Handler.java:99)

Bây giờ, tôi biết rằng đây là dự đoán, dựa trên Javadoc cho FragmentManager.beginTransaction:

Note: A fragment transaction can only be created/committed prior to an activity saving its state. If you try to commit a transaction after Activity.onSaveInstanceState() (and prior to a following Activity.onStart or Activity.onResume(), you will get an error. This is because the framework takes care of saving your current fragments in the state, and if changes are made after the state is saved then they will be lost.

Vấn đề của tôi là tôi không thể nói cách ngăn chặn nó. Tôi đã thử gọi số Handler.removeMessages() trên onPause() nhưng vẫn xảy ra. Tôi đã cố gắng thiết lập một lá cờ trong onSaveInstanceState() và không hiển thị các mảnh nếu nó được thiết lập, nhưng nó vẫn xảy ra. Điều này có vẻ giống như một vấn đề khá phổ biến, nhưng tôi không thể đưa ra một giải pháp hoạt động. Về cơ bản, làm thế nào để tôi biết rằng đoạn đã được lưu?

BTW, điều này xảy ra trên BaseActivity của tôi (mở rộng FragmentActivity), nhưng mỗi hoạt động có trình xử lý riêng của nó, vì vậy tôi không nghĩ đây là vấn đề.

Suy nghĩ cuối cùng của tôi là sử dụng Fragment.commitAllowingStateLoss(), nhưng điều đó có vẻ giống như hack.

EDIT: Dưới đây là đoạn code mà gây cho tôi vấn đề:

private final Handler mTimerHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
     switch (msg.what) { 
     case TIMER_MESSAGE_LOGOUT_WARNING: 
      // throws IllegalStateException if fragment is already saved 
      new LogoutWarningDialog().show(getSupportFragmentManager(), 
        "dialog"); 
      break; 
     } 
     } 
}; 
+0

Nói chung nó được coi là kinh nghiệm người dùng xấu để hiển thị một hộp thoại đột ngột vào những thời điểm ngẫu nhiên như thế này, vì vậy trước khi bạn cố gắng khó để tìm một công việc xung quanh , Tôi sẽ xem xét lại thiết kế của bạn. Xem [** bài đăng trên blog **] này (http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html) về chủ đề này để biết thêm thông tin. –

Trả lời

1

tôi giả sử trong câu trả lời của tôi rằng bạn đang sử dụng FragmentManager và thêm Những mảnh vỡ qua FragmentTransacts với các thẻ (hoặc id). nên về cơ bản bên trong của bạn BaseActivity bạn chỉ có thể làm điều gì đó như thế này

FragmentManager manager = getFragmentSupportedManager(); 
Fragment fragmentIWannaKnowIfexists = manager.findFragmentByTag("Tag I used to create this Fragment inside FragmentTrasnsaction") 
// or manager.findFragmentById(ID_FROM_LAYOUT) 
if(fragmentIWannaKnowIfexists != null){ 
    //we have this Fragment already 
} else { 
    // this Fragment was not added already 
} 
+0

Không, mảnh mà tôi đang cố thêm không bao giờ tồn tại. Nó là một FragmentDialog mà chỉ được tạo ra khi tôi nhận được thông báo. Tôi sẽ thêm một số mã. –

+2

Mặc dù tôi chưa bao giờ thấy vấn đề này gây ra thông báo lỗi này, bạn chắc chắn nên thử những gì Rafael gợi ý. Nếu bạn nói "nó không bao giờ tồn tại", có thể một số hộp thoại khác đã tồn tại. Thay đổi thẻ của bạn từ "hộp thoại" thành "this_specific_dialog" –

+0

Tuyệt vời. Tôi đã có một vài hộp thoại khác nhau với cùng một thẻ. Câu trả lời/nhận xét tốt. – Knossos

Các vấn đề liên quan