2016-03-21 17 views
9

Tôi đã đọc một số bài viết và câu trả lời (bao gồm this one) về mã không dùng nữa, nhưng tôi hơi bối rối về cách xử lý (cụ thể) không được chấp nhận Fragment trình xử lý sự kiện onInflate.Cách chính xác để xử lý sự kiện Fragment không được chấp nhận trênAttach và onInflate

tôi đã thay thế thực hiện của tôi

public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) 

với

public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) 

Nếu tôi chạy ứng dụng của tôi trên một máy < API23, mã thay thế không được gọi.

Nếu tôi khôi phục mã không sử dụng ban đầu (để bây giờ tôi có cả hai phương pháp được triển khai) thì mã không dùng nữa được gọi, trả về chức năng chính xác, nhưng cuộc gọi hiện đang được thực hiện theo phương thức không dùng nữa (?).

Và khi tôi chạy ứng dụng trên máy API23, có vẻ như cả hai phiên bản của trình xử lý được gọi.

Câu hỏi đặt ra là, điều gì đang xảy ra ở đây? Nếu tôi đang viết mã được cho là chạy trên cả hai phiên bản API23 và phiên bản cũ hơn, tôi có cần thực hiện các phương thức không được chấp nhận cũng như các phương thức mới không?

Và nếu đó là trường hợp, tôi có cần phải tìm ra và thực hiện các phương pháp không được chấp nhận khác "chỉ trong trường hợp" không? (Và, do đó, là có một danh sách các phương pháp phản đối để "back-mã" cho?)


UPDATE:

bây giờ tôi đã thay đổi từ việc sử dụng android.app.Fragment-android.support.v4.app.Fragment (tức là từ mẹ đẻ các mảnh vỡ để hỗ trợ các đoạn) và ứng dụng hiện đang hoạt động như mong đợi, với mã xử lý thay thế chạy cho tất cả các phiên bản và đang đi qua nguồn Android như mong đợi.

Nhưng câu hỏi vẫn còn: TẠI SAO?

Tại sao là triển khai 'bản địa' android.app.Fragment **** được chỉnh sửa? Nhìn lại các câu hỏi trước đó thì vấn đề này đã được thảo luận lại vào tháng 9 năm 2015. Vì vậy, lý do tại sao vẫn là sự cố? Và lý do tại sao nên có sự khác biệt trong việc triển khai hỗ trợ và các đoạn mã gốc sau API 11?

+0

Cảm ơn bạn đã chỉnh sửa bị khấu hao thành không dùng nữa. Tôi chưa bao giờ nhận ra mình đã rất khó đọc! :) – SimonH

Trả lời

2

Không, bạn không nên thực hiện

public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) 

Khi một phương pháp được chấp nhận, bạn có thể (nói chung) một cách an toàn sử dụng chức năng thay thế để thay thế. Kiểm tra các định nghĩa Fragment của onInflate:

public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) { 
     mCalled = true; 
     final Activity hostActivity = mHost == null ? null : mHost.getActivity(); 
     if (hostActivity != null) { 
      mCalled = false; 
      onInflate(hostActivity, attrs, savedInstanceState); 
     } 
    } 

@Deprecated 
    public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) { 
     mCalled = true; 
    } 

Như bạn thấy, onInflate(Context context...) là một phần mở rộng của onInflate(Activity activity...) và tương thích ngược. Bằng cách gọi super.onInflate(context, attrs, savedInstanceState); bên trong phương thức ghi đè của bạn, bạn có thể yên tâm giả định rằng nó sẽ hoạt động trên cả hai phiên bản API23 và phiên bản cũ hơn.

Nếu tôi chạy ứng dụng trên máy < API23, mã thay thế không phải là được gọi.

Điều đó có vẻ kỳ lạ, tôi không thể tái tạo nó, đăng nhập của tôi đã được thực hiện với một mã như thế này trong một máy không v23:

@Override 
public void onInflate(Context context, AttributeSet attrs, 
            Bundle savedInstanceState) { 
     super.onInflate(context, attrs, savedInstanceState); 
     Log.w(TAG, "I'm being executed"); 
    } 

Hãy chắc chắn rằng:

  1. Bạn đang nhập phiên bản hỗ trợ của Fragment, android.support.v4.app.Fragment thay vì android.app.Fragment và bạn sử dụng getSupportFragmentManager() thay vì getFragmentManager().
  2. Bạn có các thư viện mới nhất của support-v4appcompat-v7 cũng như compileSdkVersion 23 trong bạn build.gradle

Và khi tôi chạy ứng dụng trên một máy API23, dường như cả hai các phiên bản của trình xử lý này được gọi là.

Điều đó có thể được giải thích bằng mã onInflate(Context context...), nơi mà nếu nó được gọi bởi một hoạt động, kêu gọi onInflate(Activity activity...)

EDIT

Về update:

thực hiện Native của android.app.Fragment isn' t được coi là tương thích ngược. Mã số android.app.Fragment thường đơn giản hơn nhiều so với mã số android.support.v4.app.Fragment vì thực tế đó.

Ngoài ra, có một số tính năng trong triển khai gốc không thể được giới thiệu trong thư viện hỗ trợ do khó thiết kế hoặc vì nó không phải là ưu tiên cho nhà phát triển. Ví dụ. Trong thực hiện bản địa, trong mã nguồn onInflate() có một số sử dụng Chuyển tiếp để tạo hiệu ứng cho lối vào hoặc lối ra của đoạn mới. Đó là hư không được tìm thấy trong thư viện hỗ trợ.

+0

Cảm ơn bạn đã dành sự cố để trả lời. Tôi có thể thấy lý do tại sao cả hai phiên bản của trình xử lý được gọi cho v23. Tôi vẫn không nhận được cuộc gọi đến trình xử lý thay thế cho các phiên bản trước v23. Oddly I AM nhận được một thông điệp tường trình "I/dalvikvm: Không thể tìm thấy phương thức android.app.Fragment.onInflate, được tham chiếu từ phương thức OdometerFragment.onInflate" có vẻ lạ. Điều đó và thực tế là bước qua mã Fragment android là hiển thị các dòng nguồn sai khiến tôi tin rằng tôi không có phiên bản mới nhất của một cái gì đó. – SimonH

+0

Đảm bảo rằng: 1) bạn đang nhập phiên bản hỗ trợ của Fragment, android.support.v4.app.Fragment thay vì android.app.Fragment và bạn sử dụng getSupportFragmentManager() thay vì getFragmentManager(). 2) bạn có các thư viện mới nhất hỗ trợ-v4 và appcompat-v7 cũng như compileSdkVersion 23 trong build.gradle của bạn. – Sevle

+0

Cảm ơn bạn đã biết thêm mẹo. Tôi đã cố gắng thay đổi để 'hỗ trợ' mảnh vỡ đêm qua và nó giải quyết vấn đề cho tôi. Tôi đã cập nhật câu hỏi cho phù hợp. Tôi vẫn khá bối rối là tại sao việc thực hiện bản địa và hỗ trợ lại khác nhau. Có vẻ như một con ốc vít ở đâu đó với tôi. Có - vấn đề cụ thể của tôi được giải quyết nhưng 'app.android.Fragment' không phải là – SimonH

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