Có bao nhiêu hoạt động vs Mảnh vỡ?


185

Giới thiệu:

Mẫu "Hướng dẫn phân đoạn" cơ bản có dạng như sau:

  1. Trên máy tính bảng, có một danh sách bên trái, chi tiết bên phải.
  2. Cả hai Fragmentsvà đều cư trú trong cùng một Activity.
  3. Trên điện thoại, có một danh sách Fragmenttrong một Activity.
  4. Ra mắt một cái mới Activityvới các chi tiết Fragment.

(ví dụ: API Fragment Android 3.0 của Dianne HackbornHướng dẫn API Fragment )

Trên cả hai thiết bị, chức năng là trong Fragments. (đơn giản)

Trên Tablet , toàn bộ ứng dụng là 1Activity , trên điện thoại , có rất nhiềuActivities .


Câu hỏi:

  • Có một lý do để chia ứng dụng điện thoại thành nhiều Activities?

Một vấn đề với phương pháp này là bạn sao chép rất nhiều logic trong Máy tính bảng chính Activityvà trong Điện thoại riêng Activities.

  • Sẽ không dễ dàng hơn để giữ lại mô hình 1 Hoạt động trong cả hai trường hợp, sử dụng cùng một logic chuyển đổi Fragmentsvào và ra (chỉ sử dụng một bố cục khác)?

Bằng cách này, phần lớn logic nằm trong Fragmentschính chúng và chỉ có một Activitybản sao - ít mã trùng lặp.

Ngoài ra, những gì tôi đã đọc về ActionBarSherlocknó là nó dường như hoạt động tốt nhất Fragmentsthay vì Activities(nhưng tôi chưa làm việc với nó).

Là các hướng dẫn quá đơn giản, hoặc tôi đã bỏ lỡ một cái gì đó lớn trong phương pháp này?


Chúng tôi đã thử cả hai cách tiếp cận thành công trong văn phòng - nhưng tôi sắp bắt đầu một dự án lớn hơn và muốn làm mọi thứ dễ dàng cho bản thân nhất có thể.

Một số liên kết đến các câu hỏi liên quan:


Cập nhật

Bắt đầu tiền thưởng cho câu hỏi - vẫn chưa thuyết phục về lý do tại sao tôi cần sao chép logic ứng dụng của mình trong hoạt động máy tính bảng và trong từng hoạt động của điện thoại.

Cũng tìm thấy một bài viết thú vị của những người ở Square, rất đáng đọc:


38
+1 cho một câu hỏi tuyệt vời và được viết tốt.
Siddharth Lele

đó là điều làm tôi đau đớn nhiều ngày nay, hiện tại tôi đang làm việc trên một ứng dụng có thiết kế bao gồm nhiều mảnh vỡ và nó sẽ có sẵn trong cả điện thoại và máy tính bảng, tôi đang tìm một cách trung gian, nhưng chưa thể tìm thấy ...
Nixit Patel

1
Tôi thực sự có nghĩa là không xúc phạm nhưng tôi nghĩ bạn chỉ chấp nhận những gì bạn muốn nghe hơn là câu trả lời thực sự. Câu trả lời của Scuba không được Google khuyến nghị và bài đăng trên blog mà tôi thích để giải thích lý do.
pjco

1
@pjco Cụ thể tôi không đồng ý với việc có onItemSelected()phương thức trong Hoạt động. Trong ứng dụng "thực" của mình, tôi có nhiều danh sách & danh sách phụ. Mẫu này gợi ý rằng Hoạt động Tab của tôi phải có onItemSelected()phương pháp để xử lý từng danh sách. Ngoài ra, mỗi Hoạt động trên Điện thoại phải có cùng một logic được nhân đôi bên trong mỗi hoạt động đó. IMHO sẽ tốt hơn nhiều khi đưa logic được chọn vào từng phân đoạn - không có sự trùng lặp và tôi thích cách cấu trúc mã đó. Tôi hy vọng điều này có ích
Richard Le Mesurier

2
Tôi hiện đang treo lên vấn đề nan giải này trong công việc. Những mảnh vỡ tải nhiều nhanh hơn tung ra các hoạt động mới, vì vậy tôi bắt đầu để thực hiện một kiến trúc hoạt động duy nhất. Mặc dù vậy, tôi đã gặp phải một vấn đề, đó là dường như tôi không thể tìm thấy một cách tốt để hỗ trợ các cấu hình nhiều mảnh mà không làm gì đó hack. Xem câu hỏi này .
theblang

Câu trả lời:


41

Tôi đồng ý rằng các hướng dẫn rất đơn giản. Họ chỉ giới thiệu Fragmentsnhưng tôi không đồng ý với mô hình như đề xuất.

Tôi cũng đồng ý rằng không nên sao chép logic ứng dụng của bạn qua nhiều Hoạt động (xem Nguyên tắc DRY trên wikipedia ).


Tôi thích mẫu được sử dụng bởi ActionBarSherlockứng dụng Fragment Demo ( tải về tại đâymã nguồn tại đây ). Bản demo phù hợp nhất với hướng dẫn được đề cập trong câu hỏi là bản có tên "Bố cục" trong ứng dụng; hoặc FragmentLayoutSupporttrong mã nguồn.

Trong bản demo này, logic đã được chuyển ra khỏi Activityvà vào Fragment. Thực TitlesFragmenttế có chứa logic để thay đổi Fragment. Theo cách này, mỗi Hoạt động rất đơn giản. Để sao chép nhiều Hoạt động rất đơn giản, trong đó không có logic nào bên trong Hoạt động, làm cho nó rất đơn giản.

Bằng cách đưa logic vào các Đoạn, không cần phải viết mã nhiều lần ; nó có sẵn cho dù Hoạt động mà Mảnh vỡ được đặt vào. Điều này làm cho nó trở thành một mô hình mạnh mẽ hơn so với mô hình được đề xuất bởi hướng dẫn cơ bản.

    /**
    * Helper function to show the details of a selected item, either by
    * displaying a fragment in-place in the current UI, or starting a
    * whole new activity in which it is displayed.
    */
    void showDetails(int index)
    {
        mCurCheckPosition = index;

        if (mDualPane)
        {
            // We can display everything in-place with fragments, so update
            // the list to highlight the selected item and show the data.
            getListView().setItemChecked(index, true);

            // Check what fragment is currently shown, replace if needed.
            DetailsFragment details = (DetailsFragment) getFragmentManager()
                .findFragmentById(R.id.details);
            if (details == null || details.getShownIndex() != index)
            {
                // Make new fragment to show this selection.
                details = DetailsFragment.newInstance(index);

                // Execute a transaction, replacing any existing fragment
                // with this one inside the frame.
                FragmentTransaction ft = getFragmentManager()
                    .beginTransaction();
                ft.replace(R.id.details, details);
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.commit();
            }

        }
        else
        {
            // Otherwise we need to launch a new activity to display
            // the dialog fragment with selected text.
            Intent intent = new Intent();
            intent.setClass(getActivity(), DetailsActivity.class);
            intent.putExtra("index", index);
            startActivity(intent);
        }
    }

Một ưu điểm khác của mẫu ABS là bạn không kết thúc với Hoạt động máy tính bảng có chứa nhiều logic và điều đó có nghĩa là bạn tiết kiệm bộ nhớ. Mẫu hướng dẫn có thể dẫn đến một hoạt động chính rất lớn trong một ứng dụng phức tạp hơn; vì nó cần xử lý logic của tất cả các mảnh được đặt vào nó bất cứ lúc nào.

Nhìn chung, đừng nghĩ rằng nó bị buộc phải sử dụng nhiều hoạt động. Hãy nghĩ về nó như có cơ hội để chia mã của bạn thành nhiều đoạn và tiết kiệm bộ nhớ khi sử dụng chúng.


thx cho câu trả lời toàn diện - Tôi đã xem xét các bản demo của ABS và tôi nghĩ rằng có rất nhiều mã tốt ở đó. Thay vào đó, tôi sẽ cố gắng chuyển phần lớn logic của mình vào Mảnh vỡ
Richard Le Mesurier

Ứng dụng Demo đã được chuyển đến đây: play.google.com/store/apps/ từ
Philipp E.

Tôi nghĩ rằng mẫu mà bạn mô tả là từ mã mẫu ban đầu của Google: android-developers.blogspot.com/2011/02/. Tôi nghĩ ActionBarSherlock chỉ chuyển mã trình diễn Google để sử dụng các lớp ABS.
Dan J

17

Tôi nghĩ rằng bạn đang đi đúng hướng. (Và vâng, các hướng dẫn được đơn giản hóa quá mức).

Trong bố cục máy tính bảng, bạn có thể sử dụng một Hoạt động duy nhất và trao đổi trong và ngoài Mảnh vỡ (trong nhiều 'bảng'). Trong khi ở bố cục điện thoại, bạn có thể sử dụng Hoạt động mới cho mỗi Phân đoạn.

Thích như vậy:

nhập mô tả hình ảnh ở đây

Có vẻ như rất nhiều công việc phụ, nhưng bằng cách sử dụng nhiều hoạt động cho điện thoại, bạn kích hoạt vòng đời Hoạt động cơ bản và chuyển qua Ý định. Điều này cũng cho phép khung để xử lý tất cả các hình ảnh động và ngăn xếp ngược.

Để giúp giảm mã, bạn có thể sử dụng BaseActivityvà mở rộng từ đó.

Vì vậy, nếu người dùng có một máy tính bảng bạn sẽ sử dụng MyMultiPaneFragActivityhoặc một cái gì đó tương tự. Hoạt động này chịu trách nhiệm quản lý các cuộc gọi lại từ các đoạn và ý định định tuyến đến đoạn chính xác (chẳng hạn như mục đích tìm kiếm)

Nếu người dùng có điện thoại, bạn có thể sử dụng Hoạt động thông thường với rất ít mã và mở rộng MyBaseSingleFragActivityhoặc tương tự. Các hoạt động này có thể rất đơn giản, 5-10 dòng mã (thậm chí có thể ít hơn).

Phần khó khăn là định tuyến ý định và không có gì. * (Chỉnh sửa: xem thêm bên dưới).

Tôi nghĩ lý do đây là cách được khuyến nghị là để tiết kiệm bộ nhớ và giảm độ phức tạp và khớp nối. Nếu bạn đang trao đổi Fragment, thì FragmentManagerduy trì một tham chiếu đến Fragment đó cho stack-stack. Nó cũng đơn giản hóa những gì nên 'chạy' cho người dùng. Thiết lập này cũng tách riêng các khung nhìn và bố cục và logic trong Đoạn từ vòng đời Hoạt động. Bằng cách này, một Đoạn có thể tồn tại trong một hoạt động, bên cạnh một đoạn khác (hai ngăn) hoặc trong Hoạt động ba ngăn, v.v.

* Một trong những lợi ích của việc định tuyến mục đích thường xuyên là bạn có thể khởi chạy một Hoạt động rõ ràng từ bất kỳ đâu trong ngăn xếp ngược. Một ví dụ có thể là trong trường hợp kết quả tìm kiếm. (MySearchResults. Class).

Có một đọc ở đây để biết thêm:

http://android-developers.blogspot.com/2011/09/preparing-for-handsets.html

Nó có thể là một công việc trước mắt hơn một chút, bởi vì mỗi phân đoạn phải hoạt động tốt trong các hoạt động riêng biệt, nhưng nó thường được đền đáp. Điều đó có nghĩa là bạn có thể sử dụng các tệp bố cục thay thế xác định các kết hợp phân đoạn khác nhau, giữ mô-đun mã phân đoạn, đơn giản hóa việc quản lý thanh hành động và để hệ thống xử lý tất cả các ngăn xếp phía sau hoạt động.


Lợi thế của MySearchResults - bạn đề nghị có một cách khác để đáp ứng ý định đó tùy thuộc vào thiết bị cầm tay hoặc máy tính bảng - tại sao điều này tốt hơn là có một hoạt động duy nhất đáp ứng trong cả hai trường hợp? Bạn đề nghị, trên Tablet không có định tuyến mục đích thường xuyên - vì vậy bạn phải giải quyết vấn đề cho máy tính bảng. Tại sao không sử dụng giải pháp đó trên thiết bị cầm tay quá?
Richard Le Mesurier

Ưu điểm ở đây là mã máy tính bảng của bạn có thể mong đợi định tuyến đến nhiều bảng. Đôi khi bạn sẽ muốn thay đổi nhiều bảng trên một mục đích duy nhất. Chẳng hạn như một kết quả tìm kiếm ở bên trái với sự gièm pha của mục đầu tiên trong khung lớn hơn ở bên phải. Mã này sẽ không thể di chuyển đến một bố cục duy nhất.
pjco

Tại sao có thể chuyển đổi các đoạn khi có nhiều, nhưng nếu chỉ nhìn thấy 1 đoạn, tôi không được chuyển sang đoạn khác?
Richard Le Mesurier

Không chắc tôi hiểu ý của bạn là gì, nhưng để làm rõ nhận xét của tôi ở trên: Đôi khi bạn có thể muốn thay đổi nhiều hơn một đoạn cùng một lúc trong bố cục nhiều đoạn. Điều này yêu cầu mã để thay đổi 2 đoạn, mà bạn sẽ không sử dụng lại trong một bố cục đoạn đơn
pjco

Bạn được chào đón :) vui lòng upvote hoặc chấp nhận nếu bạn cảm thấy câu trả lời là hữu ích
pjco

6

Đây là câu trả lời của Reto Meier về vấn đề tương tự, được lấy từ video này của khóa học Cơ bản về Android của Udacity .

Có một số lý do bạn nên chia nhỏ ứng dụng của mình thành các hoạt động khác nhau.

  • Có một hoạt động nguyên khối duy nhất làm tăng độ phức tạp của mã của bạn, gây khó khăn cho việc đọc, kiểm tra và bảo trì.
  • Làm cho việc tạo và quản lý bộ lọc ý định khó hơn nhiều.
  • Tăng nguy cơ khớp chặt các thành phần độc lập.
  • Làm cho nó có nhiều khả năng đưa ra các rủi ro bảo mật nếu hoạt động đơn lẻ bao gồm cả thông tin nhạy cảm và thông tin an toàn để chia sẻ.

Một nguyên tắc tốt là tạo ra một hoạt động mới bất cứ khi nào bối cảnh thay đổi. Ví dụ: hiển thị một loại dữ liệu khác và trong khi chuyển từ xem sang nhập dữ liệu.


thú vị, tiêu đề của video là "Tại sao chúng ta không chỉ sử dụng các mảnh vỡ"
Richard Le Mesurier

đó là một cách tiếp cận tốt, đang đối mặt với vô số vấn đề với nhiều hoạt động đơn lẻ ... có lẽ là điểm kinh nghiệm thực sự
GvSharma

4

Một vấn đề với phương pháp này là bạn sao chép rất nhiều logic trong Hoạt động máy tính bảng chính và trong các Hoạt động điện thoại riêng biệt.

Trong mô hình chi tiết tổng thể, có hai hoạt động. Một hiển thị cả hai mảnh trên màn hình lớn hơn và chỉ mảnh "chính" trên màn hình nhỏ hơn. Phần còn lại hiển thị đoạn "chi tiết" trên màn hình nhỏ hơn.

Logic chi tiết của bạn nên được gắn trong các chi tiết. Do đó, không có sự sao chép mã liên quan đến logic chi tiết giữa các hoạt động - hoạt động chi tiết chỉ hiển thị đoạn chi tiết, có thể truyền dữ liệu từ phần Intentphụ.

Ngoài ra, những gì tôi đã đọc về ActionBarSherlock là nó dường như hoạt động tốt nhất với Fragment thay vì Activity (nhưng tôi chưa làm việc với nó).

ActionBarSherlock không liên quan gì đến các đoạn hơn so với thanh hành động gốc, vì ActionBarSherlock hoàn toàn là một cổng sau của thanh hành động gốc.


Suy nghĩ của bạn về ý tưởng của một hoạt động là gì?
theblang

@mattblang: Miễn là bạn điều hướng đúng, không có vấn đề gì với điều đó.
CommonsWare

1
Tôi đã thử tái cấu trúc thành một kiến ​​trúc hoạt động đơn lẻ vì việc thay thế một đoạn nhanh hơn nhiều so với việc khởi chạy một hoạt động mới với cùng một đoạn trong đó. Tôi cảm thấy như tôi đang chạy vào quá nhiều snags, như thế này . Hầu hết các ví dụ tôi tìm thấy trực tuyến, đặc biệt đối với các cấu hình nhiều phân đoạn như chi tiết chính, không sử dụng một hoạt động nào. Vì vậy, tôi đang ở trong một chút khó xử.
theblang

0

Đề cập đến câu hỏi đầu tiên của "Có lý do để chia ứng dụng điện thoại thành nhiều Hoạt động không?" - Đúng. nó chỉ đơn giản là đi vào không gian có sẵn, một Tablet mang lại nhiều chỗ hơn cho các nhà phát triển, do đó cho phép các nhà phát triển đặt nhiều hơn trên một màn hình. Android cho chúng ta biết rằng Hoạt động có thể cung cấp màn hình . Vì vậy, những gì bạn có thể làm với 1 màn hình lớn trên máy tính bảng, là thứ có thể phải trải trên nhiều màn hình trên điện thoại, vì không đủ chỗ cho tất cả các mảnh vỡ.


Câu thứ nhất - "Hoạt động là một thành phần ứng dụng cung cấp màn hình mà người dùng có thể tương tác để làm gì đó". Tôi thấy có lỗi trong tuyên bố ban đầu của mình, tôi không có ý đặt "là một màn hình khác",
EFlisio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.