2010-07-29 34 views
15

Tôi muốn Hoạt động trên ngăn Hoạt động của ứng dụng của tôi chỉ có một phiên bản. Tôi có một số màn hình là ListActivities và tôi không muốn đi qua nỗi đau và đau khổ của việc cập nhật các danh sách trong một phiên bản trước của ListActivity khi một thể hiện khác của ListActivity đó được thay đổi (thêm vào, chỉnh sửa, loại bỏ, vv) (hoặc là có một cách dễ dàng để làm điều này?).startActivityForResult không hoạt động đúng với launchMode singleInstance

Lưu ý: Tôi đã đọc rằng SingleTop sẽ thực hiện điều này (mặc dù nó phá hủy Hoạt động nếu bạn nhấn nút quay lại), nhưng nó không hoạt động. Tôi có một trình đơn và nếu tôi truy cập vào màn hình Hộp thư đến, sau đó tôi truy cập vào màn hình Danh sách phát nhanh của mình, sau đó tôi truy cập lại vào màn hình Hộp thư đến, nó sẽ tạo một Hoạt động hộp thư đến mới.

Ngay bây giờ, trên ListActivities của tôi, tôi đã launchMode được đặt thành singleInstance. Vấn đề là: Nếu tôi khởi chạy một Activity khác bằng startActivityForResult, trình xử lý onActivityResult sẽ kích hoạt ngay lập tức (trước khi Activity mới được tạo). Khi tôi thực hiện thao tác cần thiết trên màn hình tiếp theo để trả về kết quả, trình xử lý onActivityResult không kích hoạt.

Điều gì đang xảy ra?

Sau đây là cách tôi cháy Hoạt động mới:

Intent intentLaunchQuickList = new Intent(ActivityMyList.this, ActivityQuickList.class); 
startActivityForResult(intentLaunchQuickList, REQUEST_QUICKLIST); 

Dưới đây là cách tôi trả lại kết quả:

@Override 
protected void onListItemClick(ListView l, View v, int position, long id) { 
    super.onListItemClick(l, v, position, id); 
    QuickListItem qlItem = m_Adapter.getItem(position); 
    if (qlItem != null && qlItem.getQLId() != -1) { 
     Intent data = new Intent(); 
     data.putExtra("ql_id", qlItem.getQLId()); 
     if (getParent() == null) { 
      setResult(Activity.RESULT_OK, data); 
     } 
     else { 
      getParent().setResult(Activity.RESULT_OK, data); 
     } 
    } 
    finish(); 
} 

Đây là handler onActivityResult tôi:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == REQUEST_QUICKLIST) { 
     if (resultCode == Activity.RESULT_OK) { 
      Bundle extras = data.getExtras(); 
      if (extras != null) { 
       int id = extras.getInt("ql_id"); 
       if (id > 0) { 
        launchQLItemsThread(id); 
       } 
      } 
     } 
    } 
} 

Trả lời

21

Từ tài liệu của startActivityForResult: "Ví dụ: nếu hoạt động bạn đang khởi chạy sử dụng singleTask chế độ khởi động, nó sẽ không chạy trong nhiệm vụ của bạn và do đó bạn sẽ ngay lập tức nhận được kết quả hủy. " singleInstance hoạt động giống nhau.

Nói cách khác, nếu bạn muốn sử dụng sAFR, bạn sẽ cần xử lý nhiều phiên bản hoạt động. Những gì tôi sẽ tư vấn là lưu trữ trạng thái danh sách cho các trường hợp ListActivity của bạn trong tới một số điểm ứng dụng toàn cầu (một đơn hoặc bất kỳ thứ gì) và tải từ đó trong onResume. Sau đó, ngay cả khi nhiều trường hợp ListActivity sẽ được tạo, phần đầu sẽ luôn cập nhật dữ liệu trước khi các dữ liệu cũ được tiếp tục và danh sách sẽ luôn xuất hiện hiện tại cho người dùng.

Lưu ý rằng bạn vẫn nên làm điều đó nếu dữ liệu của bạn có nghĩa là liên tục, vì toàn bộ quá trình của bạn có thể bị hệ thống giết bất cứ lúc nào sau khi gọi và nếu bạn chưa lưu bất kỳ thay đổi nào thời gian trở lại, họ có trách nhiệm bị mất âm thầm dưới một số - thường là những trường hợp hiếm hoi và không thể đoán trước được. Trong trường hợp này, bạn muốn sử dụng các tệp cục bộ hoặc các cơ sở dữ liệu SQLite, không phải là sự tồn tại của mạng. cần quay lại nhanh vì người dùng không thể tương tác với hệ thống trong khi đang chạy, do đó hãy lưu vào bộ nhớ cục bộ và sau đó đồng bộ hóa với mạng vào một thời điểm khác, có thể thông qua dịch vụ được khởi chạy bởi .

+0

Cảm ơn bạn đã phản hồi. Tôi hiểu những gì bạn muốn tôi làm, tuy nhiên, nó sẽ không gây ra vấn đề? Tôi rõ ràng sẽ cần phải làm điều tương tự trong trình xử lý onSaveInstanceState và onRestoreInstanceState. Nếu on onResume và onPause tôi đọc và lưu thông tin từ cơ sở dữ liệu, ứng dụng của tôi sẽ đọc không cần thiết từ cơ sở dữ liệu và đọc từ SavedInstanceState nếu nó đã từng gõ trình xử lý onRestoreInstanceState, phải không? Ngoài ra, đây có phải là thực tế phổ biến cho các nhà phát triển Android không? Lưu dữ liệu ListActivity vào một singleton cho nhiều phiên bản của ListActivity? Một lần nữa, cảm ơn bạn đã giúp đỡ – Andrew

+0

Ngoài ra, bạn có thể giải thích tại sao singleTop không hoạt động đối với tôi không? Hay tôi không hiểu nó? – Andrew

+0

SavedInstanceState chỉ hữu ích cho việc khôi phục trạng thái của một cá thể cụ thể của một hoạt động; sử dụng nó để lưu vị trí cuộn, vv, không liệt kê nội dung. Những gì bạn muốn làm là có tất cả các trường hợp hoạt động của bạn chia sẻ một số trạng thái, vì vậy bạn muốn đặt trạng thái đó trong cơ sở dữ liệu nếu nó tồn tại hoặc trong một thành viên tĩnh nếu nó chỉ là một bộ nhớ cache dữ liệu từ mạng.Tôi đề nghị cái sau dựa trên những gì bạn đã nói; chỉ cần sử dụng một DB để giữ dữ liệu bạn vẫn cần phải gửi qua mạng trong tương lai để bạn không bị mất nó. –

1

Tôi có một số màn hình là ListActivities và tôi muốn không đi vượt qua nỗi đau và đau khổ của cập nhật các danh sách trong một dụ trước của ListActivity khi một ví dụ của ListActivity rằng là đã thay đổi (hoặc có cách nào dễ dàng để thực hiện việc này không?).

Sử dụng mô hình nhất quán. Ví dụ, dữ liệu của bạn hy vọng trong một cơ sở dữ liệu. Mỗi ListActivityCursor trên phần cơ sở dữ liệu cần thiết. Có Cursor là "Con trỏ được quản lý" (qua startManagingCursor()) và ListViews của bạn sẽ tự động cập nhật trong onResume(). Sau đó, bạn thực hiện các thay đổi đối với mô hình của mình thông qua cơ sở dữ liệu.

Tôi có một menu và nếu tôi đi đến màn hình Inbox tôi, sau đó tôi đi đến màn hình phát nhanh của của tôi, và sau đó tôi đi đến màn hình Inbox tôi một lần nữa, nó tạo ra một mới Hoạt động Inbox .

Đó là những gì nó được cho là phải làm. Trích dẫn documentation:

Các chế độ "chuẩn" và "singleTop" khác nhau chỉ trong một tôn trọng: Mỗi khi có mới ý định cho một hoạt động "chuẩn", một dụ mới của lớp được tạo ra để trả lời ý định đó. Mỗi trường hợp xử lý một mục đích duy nhất. Tương tự, phiên bản mới của hoạt động "singleTop" cũng có thể được tạo để xử lý mục đích mới. Tuy nhiên, nếu tác vụ đích đã có một phiên bản hiện tại của hoạt động ở đầu ngăn xếp của nó, trường hợp đó sẽ nhận được ý định mới (trong một cuộc gọi onNewIntent()); a phiên bản mới không được tạo. Trong hoàn cảnh khác - ví dụ, nếu một thể hiện của "singleTop" hoạt động là trong nhiệm vụ mục tiêu , nhưng không phải ở phía trên cùng của ngăn xếp, hoặc nếu nó ở trên cùng của một chồng, nhưng không phải trong nhiệm vụ mục tiêu - một phiên bản mới sẽ được tạo và đẩy trên ngăn xếp.

(đậm thêm để nhấn mạnh)

Ngay bây giờ, trên ListActivities tôi, tôi có launchMode thiết lập để singleInstance.

Vui lòng không làm điều này.

+0

Cảm ơn bạn đã phản hồi. Bạn có thể vui lòng cung cấp cho tôi các liên kết đến một số thông tin hữu ích về các con trỏ và cơ sở dữ liệu được quản lý không? Tôi chưa triển khai cơ sở dữ liệu trong ứng dụng Android. – Andrew

+0

Hiện tại (tôi đã bắt đầu ứng dụng này tuần trước và đây là ứng dụng đầu tiên của tôi) Tôi chỉ đang lấy dữ liệu từ các dịch vụ web của mình và điền vào danh sách. Rõ ràng việc tạo một thể hiện mới của Activity sau đó sẽ cần phải kéo dữ liệu từ dịch vụ web một lần nữa. Đây là lý do tại sao tôi bắt đầu sử dụng singleInstance. Tôi hiểu logic đằng sau những gì bạn đang nói. Tôi vẫn chưa thực hiện bất cứ điều gì như thế; vì vậy một số tài nguyên sẽ hữu ích. Cảm ơn một lần nữa – Andrew

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