18

tôi đã thực hiện một Hoạt động rất đơn giản trong đó cho thấy một đơn giản ListFragment như dưới đây:mã rất đơn giản, nhưng đã nhận lỗi "hoạt động đã bị phá hủy" khi sử dụng Fragment

Hoạt động của tôi:

public class MyActivity extends FragmentActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      FragmentManager fragMgr = getSupportFragmentManager(); 

      FirstFragment list = new FirstFragment(); 
      fragMgr.beginTransaction().add(android.R.id.content, list).commit(); 
    } 

} 

ListFragment của tôi:

public class FirstFragment extends ListFragment{ 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     inflater.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View view = inflater.inflate(R.layout.main, null); 
     return view; 
    } 


    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     String listContent[] = {"Larry", "Moe", "Curly"}; 
     setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, listContent)); 
    } 
    ... 
} 

Khi tôi bắt đầu ứng dụng của tôi, tôi đã thông báo lỗi:

java.lang.IllegalStateException: Activity has been destroyed 
E/AndroidRuntime( 947): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 
E/AndroidRuntime( 947): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 
E/AndroidRuntime( 947): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 
E/AndroidRuntime( 947): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 
E/AndroidRuntime( 947): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 947): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime( 947): at android.app.ActivityThread.main(ActivityThread.java:4363) 
E/AndroidRuntime( 947): at java.lang.reflect.Method.invokeNative(Native Method) 
... 

Nó phàn nàn rằng hoạt động đã bị phá hủy, Tại sao ???

P.S. main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:paddingLeft="8dp" 
    android:paddingRight="8dp"> 

    <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="next" /> 

    <ListView 
    android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#00FF00" 
    android:layout_weight="1" 
    android:drawSelectorOnTop="false" /> 

    <TextView 
    android:id="@android:id/empty" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#FF0000" 
    android:text="No data" /> 
</LinearLayout> 

Trả lời

28

Tôi đã tìm ra chính mình, Đó là vì tôi đã bỏ lỡ super.onCreate(savedInstanceState); trong phương thức onCreate hoạt động của tôi. Sau khi thêm vào, mọi thứ đều ổn.

+1

Lưu ý rằng bạn có thể chấp nhận câu trả lời của bạn là câu trả lời tốt nhất –

+6

Nếu một số người có thể giải thích lý do sâu sắc, tôi sẽ chấp nhận cái tốt hơn không phải của tôi :) –

+1

Trong trường hợp của tôi, tôi đã gọi super.onCreate (savedInstanceState); sau khi thêm đoạn. – Ankit

2

Chỉ để đảm bảo rằng tôi thấy quyền này, MyActivity là hoạt động mà bạn đang cố gắng khởi chạy và sau đó thêm một thể hiện của FirstFragment vào, phải không?

Ngay lập tức tôi thấy hai điều mà bạn cần phải nhìn vào

1) Trong hoạt động của bạn, bạn không bao giờ gọi setContentView() hoặc super.onCreate(). Cuộc gọi đầu tiên có thể là vấn đề lớn đối với bạn vì điều đó có nghĩa là bố cục của bạn không bao giờ bị thổi phồng và do đó, biến R không tồn tại

2) MyActivity cần phải có tệp bố cục xml riêng của nó không có.

+0

Xin chào, tôi không nghĩ rằng Hoạt động phải có tệp bố cục, ví dụ: mã của tôi đang hoạt động sau khi tôi thêm super.onCreate (...), Hoạt động của tôi chỉ lưu trữ Phân đoạn và Phân đoạn sẽ tăng bố cục cho hiển thị, không phải Hoạt động. –

+0

Có thể vì tôi chưa thực sự sử dụng gói hỗ trợ nhiều. Hầu hết sự phát triển của tôi là trên Honeycomb sử dụng bố cục nhiều ngăn. Tôi chỉ đang xem tài liệu API và tôi nghĩ bạn đã đúng. Cảm ơn bạn đã chỉ ra điều này! –

+0

Không vấn đề gì, tôi cũng mới tham gia gói hỗ trợ, tôi bắt đầu tìm hiểu đoạn từ ngày hôm nay :) –

4

Để đưa ra một lời giải thích:

Khung tạo Activity và gọi Activity.onCreate().

Activity.onCreate() bằng cách nào đó sẽ đính kèm vào FragmentManager để thông báo cho bạn biết về hoạt động lưu trữ. Activity.onDestroy() sẽ hủy đăng ký lại.

Bây giờ, bạn mở rộng Activity và ghi đè onCreate(). Bạn gọi điện đến số FragmentManager mà không cần gọi đến số Activity.onCreate(). Toàn bộ logic đăng ký được giải thích ở trên không được thực thi. Do đó, FragmentManager không biết bất kỳ điều gì về hoạt động và giả định rằng nó đã bị hủy và tạo ra ngoại lệ với thông báo lỗi gây hiểu lầm.

68

Tôi cũng gặp phải sự cố tương tự.
Tôi nhận ra rằng điều này đã xảy ra vì hoạt động này đã bị hủy trong khi FragmentTransaction sắp sửa nhận được .commit().

Giải pháp cho điều này là để kiểm tra xem liệu Activity.isFinishing() có đúng hay không.

if (!isFinishing()) { 
    FragmentTransaction ft = getSupportFragmentManager() 
    .beginTransaction(); 
    ft.replace(SOME_RES_ID, myFragmentInstance); 
    ft.commit(); 
} 
+0

Cảm ơn nó đã làm việc cho tôi! Đến đây thông qua một [thảo luận về Github] (https://github.com/JakeWharton/ActionBarSherlock/issues/1031). Cám ơn vì đã chia sẻ. –

1

những gì tôi đã làm là ngay sau khi cam kết tôi gọi

fragmentManager.executePendingTransactions();

và không bao giờ cố gắng cam kết sau khi onpause() gọi

đọc Artical Fragment Transactions & Activity State Loss

10

tôi phải đối mặt với vấn đề này cùng và không thể sửa nó. Sự kiện tôi đã thêm isFinishing() cũng như kiểm tra. nhưng không may mắn.

sau đó tôi đã thêm một séc nữa isDestroyed() và hoạt động tốt ngay bây giờ.

if (!isFinishing() && !isDestroyed()) { 
    FragmentTransaction ft = getSupportFragmentManager() 
    .beginTransaction(); 
    ft.replace(LAYOUT_ID, myFragmentInstance); 
    ft.commit(); 
} 
+1

Lưu ý rằng 'onDestroyed()' đã được thêm vào ở cấp API 17. – Gira

0

super.onCreate (savedInstanceState) sẽ gọi onCreate phương pháp trong FragmentActivity, mà sẽ gọi mFragments.attachHost(null /*parent*/);

Câu này sẽ gán giá trị cho mHost trong FragmentController, khi bạn gọi FragmentTransaction.commit(),

Trong phương pháp enqueueAction(), nó có câu này

if (mDestroyed || mHost == null) { 
     throw new IllegalStateException("Activity has been destroyed"); 
} 

Vì vậy, nếu bạn đã không gọi super.onCreate (savedInstanceState) trước khi bạn cam kết một fragmentTransaction, bạn sẽ nhận được ngoại lệ này vì mHost là null

0

Nếu bất kỳ một loại đi qua vấn đề tương tự:

tôi đã phải đối mặt với cùng một thời điểm vấn đề, nhưng trong trường hợp của tôi từ Hoạt động chính, tôi đã gọi đến Fragment1 và sau đó nếu người dùng nhấp vào Fragment1 Layout, tôi muốn khởi chạy một Layout Fragment2 khác.

Tôi đã có thể khởi chạy Fragment1 từ Hoạt động chính nhưng Fragment1 thành Fragment2 đã thất bại với ngoại lệ là "Hoạt động đã bị hủy".

Tôi đã giải quyết vấn đề trên bằng cách duy trì đối tượng FragmentManager tĩnh trong lớp MainActivity. riêng tĩnh FragmentManager mfragmentManager = null;

gọi tới cả hai đoạn bằng cách sử dụng cùng một đối tượng trên, đã giải quyết được sự cố của tôi.

Dưới đây là mã chuyển đổi Phân đoạn của tôi từ Hoạt động chính.

public void switchToFragment(String fragmentName){ 
     Fragment fragment = null; 
     switch (fragmentName) { 
      case "Fragment1":{ 
       fragment = new Fragment1(); 
       break; 
      } 
      case "Fragment2": { 
       fragment = new Fragment2(); 
       break; 
      } 
     } 

     FragmentTransaction transaction = mfragmentManager.beginTransaction(); 
     transaction.replace(R.id.fragment_container, fragment); 
     transaction.commit(); 
    } 
1

Tuy xấu, vì đã nhận lỗi “hoạt động đã bị phá hủy”

ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss(); 

Vì vậy, giải pháp của tôi là thêm kiểm tra if (!isFinishing()&&!isDestroyed())

if (!isFinishing()&&!isDestroyed()) { 
         fragmentTransaction.commitAllowingStateLoss(); 
        } 
       } 
Các vấn đề liên quan