2012-10-15 13 views
19

Tài liệu Android gợi ý rằng để giao tiếp từ một hoạt động với một đoạn được lưu trữ, đoạn có thể xác định giao diện gọi lại và yêu cầu hoạt động của máy chủ thực hiện nó. Mẫu cơ bản liên quan đến việc triển khai onAttach trong đoạn của bạn và truyền hoạt động đó sang một đoạn mã gọi lại. Xem http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity.Có thích hợp hơn khi sử dụng Activity.onAttachFragment hoặc Fragment.onAttach để giao tiếp giữa một Hoạt động và một đoạn lồng nhau không?

Dưới đây là ví dụ về việc cung cấp một đoạn dữ liệu khởi tạo nào đó, cũng như nghe một cuộc gọi lại điều hướng.

public class HostActivity extends Activity implements FragmentHost { 
    @Override 
    UiModel getUiModel() { 
    return mUiModel; 
    } 
    @Override 
    FragmentNavListener getNavListener() { 
    return mNavListener; 
    } 
... 
} 

public class HostedFragment extends Fragment { 
    @Override 
    public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    if (activity instanceof FragmentHost) { 
     FragmentHost host = (FragmentHost) activity; 
     setUiModel(host.getUiModel()); 
     setNavListener(host.getFragmentNavListener()); 
    } 
    } 
    ... 
} 

Hãy so sánh này để sử dụng onAttachFragment trong hoạt động máy chủ để khởi tạo một cách rõ ràng đoạn:

public class HostActivity extends Activity { 
    @Override 
    public void onAttachFragment(Fragment fragment) { 
    super.onAttachFragment(fragment); 
    if (fragment instanceof HostedFragment) { 
     HostedFragment hostedFragment = ((HostFragment) fragment); 
     hostedFragment.setUiModel(mUiModel); 
     hostedFragment.setNavListener(mNavListener); 
    } 
    } 
    ... 
} 

Đối với tôi, nó có vẻ như mô hình đầu tiên có một số nhược điểm:

  1. Nó làm đoạn khó sử dụng hơn từ các hoạt động khác nhau, kể từ vì tất cả các hoạt động đó phải triển khai giao diện bắt buộc. Tôi có thể tưởng tượng các trường hợp mà một thể hiện phân đoạn đã không yêu cầu được cấu hình đầy đủ bởi hoạt động của máy chủ, nhưng tất cả các hoạt động máy chủ tiềm năng sẽ cần phải thực hiện giao diện máy chủ.
  2. Điều này làm cho mã hơi khó theo dõi hơn đối với một người không quen với mẫu đang được sử dụng. Việc khởi tạo mảnh trong onFragmentAttached có vẻ dễ theo dõi hơn, vì mã khởi tạo tồn tại trong cùng một lớp tạo ra đoạn.
  3. Đơn vị kiểm tra bằng cách sử dụng thư viện như Robolectric trở nên khó khăn hơn, vì khi gọi onAttach, bây giờ bạn phải thực hiện FragmentHost thay vì chỉ gọi onAttach (Hoạt động mới().

Đối với những người bạn, những người đã thực hiện hoạt động để giao tiếp đoạn, những gì mô hình để bạn tìm thấy một lợi thế, và tại sao? có hạn chế việc sử dụng onAttachFragment từ hoạt động chủ?

Trả lời

6

tôi không thể nói chuyện cá nhân liên quan đến thử nghiệm với nhưng có thay thế cho giao tiếp đoạn/hoạt động giao diện gọi lại.

Ví dụ phong phú, bạn có thể sử dụng một xe buýt sự kiện để tách rời các mảnh vỡ và hoạt động của bạn. Một xe buýt sự kiện tuyệt vời có thể tìm thấy ở đây:

Otto - An event Bus by Square

Nó đang tích cực được phát triển bởi một số kỹ sư rất tài năng tại quảng trường. Bạn cũng có thể sử dụng LocalBroadcastManager được đóng gói trong Thư viện hỗ trợ Android.

LocalBroadcastManager

Eric Burke từ vuông có một bài thuyết trình nơi ông đề cập đến cả hai có thể được tìm thấy ở đây:

Android App Anatomy

+0

Otto hiện không còn được dùng nữa – Louis

2

Tôi đã sử dụng mô hình Fragment.onAttach(...) trong dự án cuối cùng của tôi.Tôi thấy hai lợi thế:

  1. bạn có thể kiểm tra sớm mà các hoạt động lưu trữ cài đặt giao diện yêu cầu và ném một ngoại lệ nếu không
  2. có ít nguy cơ nắm giữ một tài liệu tham khảo của bối cảnh lưu trữ sau khi đoạn đã được tách ra

để tận dụng 2., bạn không phải lưu trữ tài liệu tham khảo để UiModelNavListener, như bạn làm trong mẫu mã của bạn. Thay vào đó, bất cứ khi nào bạn muốn tương tác với các trường hợp này, bạn nên sử dụng mã như ((FragmentHost) getActivity).getNavListener().onNav(this) hoặc cách khác ((FragmentHost) getActivity).onNav(this). Bạn có thể lưu trữ máy chủ phân mảnh trong một trường mà bạn đặt thành null trong onDetach(...) làm phương pháp tiếp cận trung gian, nếu bạn muốn tránh việc truyền liên tục.

Tôi đồng ý rằng việc khởi tạo một đoạn từ hoạt động tạo ra nó có vẻ trực quan hơn.

Có nói tất cả điều đó, tôi sẽ bỏ qua các mảnh hoàn toàn trong dự án hiện tại của tôi. Bài đăng sau đây phản ánh các bài học kinh nghiệm từ bài cuối cùng của tôi khá tốt: https://corner.squareup.com/2014/10/advocating-against-android-fragments.html

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