6

Để tập trung vào vấn đề, tôi sẽ đơn giản hóa trường hợp sau đây - Tôi có hoạt động A và một đoạn F đang thêm một đoạn khác Trẻ em. Mã đơn giản của mỗi làNgoại lệ khi cố gắng lưu trạng thái phân đoạn lồng nhau [Fragment không còn tồn tại cho android key: target_state]

Hoạt động Một

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // do some stuff 
    FragmentManager fm = getSupportFragmentManager(); 
    F f = new F(); 
    fm.beginTransaction() 
      .add(R.id.content, f) 
      .commit(); 
} 

Fragment F

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    // do some stuff 
    FragmentManager fm = getChildFragmentManager(); 
    FragmentTransaction transaction = fm.beginTransaction(); 
    ChildFragment childFragment = new ChildFragment(); 
    childFragment.setTargetFragment(this, 1); 
    transaction.add(R.id.f, childFragment); 
    transaction.commit(); 

    return view; 
} 

mã của đoạn đứa trẻ không liên quan đến vấn đề vì vậy tôi wont đăng nó.

Sử dụng mã tất cả mọi thứ này dường như hoạt động cho đến khi tôi tích hợp căn cứ hỏa lực và bắt đầu nhận được sự sụp đổ của báo cáo sau đây

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.test/com.test.test.A}: java.lang.IllegalStateException: Fragment no longer exists for key android:target_state: index 1 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429) 
    at android.app.ActivityThread.access$800(ActivityThread.java:151) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342) 
    at android.os.Handler.dispatchMessage(Handler.java:110) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:5341) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) 
    at dalvik.system.NativeStart.main(Native Method) 

Lúc đầu, tôi không thể tái tạo các ngoại lệ nhưng sau khi thử nghiệm trong một thời gian tôi thấy rằng nếu tùy chọn nhà phát triển Không giữ hoạt động đang diễn ra gần như mỗi lần tôi đưa hoạt động lên nền và tiếp tục hoạt động. Tôi nghĩ rằng trong trường hợp bình thường nó sẽ xảy ra khi hoạt động được đặt trong nền và ứng dụng bị phá hủy.

Sau khi thực hiện một số nghiên cứu, tôi đi đến kết luận rằng lý do thực sự cho vụ tai nạn là đoạn F được đặt làm mảnh đích cho con của nó. Tôi có thể xác nhận rằng nếu tôi không đặt đoạn đích thì sự cố không xảy ra.

Tôi không chắc chắn lắm nhưng có vẻ như lý do của vụ tai nạn là phân đoạn con và phân đoạn mục tiêu của nó nằm trong các trình phân mảnh khác nhau. Vì vậy, điều đầu tiên tôi đã thử là đặt tất cả các mảnh vỡ trong trình quản lý phân đoạn của hoạt động.

Fragment F

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    // do some stuff 
    // I do not want to use private fragment manager but rather use the activity's 
    // FragmentManager fm = getChildFragmentManager(); 
    FragmentManager fm = getFragmentManager(); 
    // do the other stuff 
} 

này đã giải quyết được vấn đề. Nhưng dẫn đến một số khác. Khi tôi loại bỏ các mảnh từ hoạt động (tôi muốn thay thế nó bằng một mảnh khác). Đoạn con không thể lưu trạng thái của nó bởi vì nó có một tham chiếu đến đoạn cha của nó được loại bỏ khỏi trình quản lý.

Process: com.test.test, PID: 11047 java.lang.IllegalStateException: Failure saving state: ChildFragment{423c10f0 #1 id=0x7f0b0058} has target not in fragment manager: F{423c0f88} 
    at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:2618) 
    at android.support.v4.app.FragmentController.saveAllState(FragmentController.java:134) 
    at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:571) 
    at android.support.v7.app.AppCompatActivity.onSaveInstanceState(AppCompatActivity.java:515) 
    at android.app.Activity.performSaveInstanceState(Activity.java:1157) 
    at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1229) 

tôi có thể cố gắng đi sâu hơn và để loại bỏ các mảnh vỡ con khi mẹ của nó được lấy ra nhưng tôi có cảm giác đây không phải là cách đúng đắn để làm điều này, sau khi tất cả Tôi nghĩ rằng cách thích hợp để làm điều này là sử dụng getChildFragmentManager().

Bất kỳ trợ giúp, đề xuất, hướng dẫn nào về chủ đề sẽ được đánh giá cao.

+0

Tại sao bạn không tạo và thêm phân đoạn chỉ từ một nơi - hoạt động A? – helleye

+0

Nó sẽ làm cho mảnh không thể tái sử dụng được. Tất cả các hoạt động thêm phân đoạn cũng phải thêm đoạn con. –

+0

Bạn đã thử https://code.google.com/p/android/issues/detail?id=54520 – Krish

Trả lời

3

Tôi đã thay đổi mã của bạn như thế này và nó đang làm việc cho tôi, Thay đổi ActivityA như thế này,

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity); 

     FragmentManager fm = getSupportFragmentManager(); 
     if (fm.findFragmentById(R.id.content) == null) { 
      F f = new F(); 
      fm.beginTransaction() 
        .add(R.id.content, f) 
        .commit(); 
     } 
    } 

Và bạn có thể sử dụng thực hiện trước đó của bạn như setTargetFragment cho đoạn ChildFragment. Điều này giải quyết được ngoại lệ đầu tiên mà bạn đã đề cập trong câu hỏi.

+0

@MojoRisin Bạn đã thử câu trả lời của tôi chưa? – Krish

+0

Dường như tôi đang tìm kiếm giải pháp sai chỗ. Như bạn đã chỉ ra vấn đề là tôi đã thêm phân đoạn bất kể nó đã ở đó chưa. –

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