2012-02-21 4 views
5

Tôi đang cố gắng để truyền dữ liệu từ một hoạt động khác thông qua Intent.putExtras như thế này:Giới hạn kích thước Intent.putExtras?

private ArrayList<HashMap<String, String>> mGroups = new ArrayList<HashMap<String, String>>(); 
private ArrayList<HashMap<String, String>> mUsers = new ArrayList<HashMap<String, String>>(); 
... 

Bundle data = new Bundle(); 
data.putInt("mode", mode); 
data.putSerializable("groups", (Serializable) mGroups); 
data.putSerializable("users", (Serializable) mUsers); 
data.putInt("current_class", mCurrentClassId); 
data.putInt("current_user", mCurrentUserId); 

Intent intent = new Intent(ctx, ChildActivity.class); 
intent.putExtras(data); 
ctx.startActivityForResult(intent, 0); 

Dưới đây là một mUsers Danh sách HashMap<String,String> với dữ liệu của người sử dụng, bao gồm cả ảnh Base64 mã hóa, tổng của chuỗi kích thước trong này danh sách là khoảng 500Kb

Gọi tới startActivityForResult treo trong vài phút với màn hình màu đen và sau đó tôi nhận được lỗi ANR. Hoạt động của Sub-Activity là onCreate hoàn toàn không được gọi.

Nếu tôi không thêm chuỗi lớn vào mUsers (không có ảnh được mã hóa Base64) - chỉ hoạt động tốt.

Vui lòng trợ giúp.

+0

Hãy thử sử dụng một kiện. http://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents – DunClickMeBro

+0

Bạn đã thử luồng ý định với 'java.lang. Runnable'? –

+1

Có lẽ bạn sẽ được phục vụ tốt hơn bằng cách đặt 'ArrayList' này vào một Singleton, bạn sẽ có thể truy cập nó từ mọi 'Hoạt động' trong ứng dụng của bạn. –

Trả lời

7

nếu cả hai hoạt động là của bạn, hãy sử dụng mô hình dữ liệu phong nha. Android không khuyến khích nhiều ứng dụng được thiết kế rất tốt. Hoặc biến nó khác đi, nó cho phép ứng dụng phát triển nhanh và không quảng bá nhiều nguyên tắc ứng dụng phần mềm tốt.

Giải pháp của @ Jean-Philippe Roy (québec?) Rất thú vị nhưng singleton khá là chống mẫu khi nói đến những điều phức tạp hơn, cụ thể là các mô hình statefull hoặc serviceS.

Tùy chọn tốt nhất là sử dụng lớp ứng dụng. Lớp học này là singleton của bạn, tự nhiên trong Android. Vì vậy,

  • xác định một lớp ứng dụng trong manifest
  • của bạn cung cấp một phương pháp tĩnh để truy cập đối tượng duy nhất của lớp ứng dụng (nó luôn luôn là một singleton).
  • cho nó một phương pháp tiếp nhận và tổ chức dữ liệu của bạn, gọi nó là từ hoạt động đầu tiên của bạn
  • và một thứ hai để có được chúng trở lại trong hoạt động thứ hai của bạn

--- Cập nhật sau câu trả lời @ straya và Hơn 18 tháng lập trình Android :)

Câu hỏi về việc chia sẻ cấu trúc dữ liệu hoặc quy trình liên quan đến ứng dụng, hoạt động, lượt xem, phân đoạn luôn có trong đầu khi xây dựng ứng dụng Android. Điều quan trọng là phải biết và xem xét phạm vi ứng dụng là đúng nơi để giữ cấu trúc được chia sẻ, nhưng việc sử dụng chính lớp ứng dụng để đặt cấu trúc dữ liệu trong phạm vi đó là không khả thi liên quan đến:

  • chất lượng mã, nếu tất cả các cấu trúc dữ liệu được chia sẻ và quy trình đều biết về ứng dụng, nó sẽ nhanh chóng trở nên cồng kềnh với các trình truy cập cho tất cả các thực thể đó.
  • chỉ có một hồ bơi chung toàn cầu của tổ chức, mà không tìm đủ hạt và có thể dẫn đến khó có thể phát hiện cách của đơn vị khớp nối

bây giờ tôi có xu hướng thích sử dụng Dependency Injection độc thân quản lý. Dagger hoặc RoboGuice cho phép tạo và tiêm một cá thể duy nhất của một lớp đã cho vào các lớp khác. Kỹ thuật này và DI thường cung cấp khả năng tuyệt vời cho các thiết kế Android tốt:

  • không làm giảm chất lượng mã, thậm chí nó còn được rút ngắn khá nhiều. Sử dụng @Inject để tiêm phụ thuộc và chúng sẽ được tiêm.
  • không cung cấp 2 trách nhiệm cho lớp đơn lẻ: nó sẽ không xử lý việc tạo cá thể đơn lẻ, khung làm việc sẽ thực hiện.
  • dễ dàng hơn để chuyển từ một singleton sang một trường hợp bình thường
  • vì những đơn đó trở thành các lớp bình thường với chú thích đơn giản, chúng không chứa các phương thức tĩnh nữa và điều này cho phép mô phỏng chúng rất dễ dàng. Và đó là một điểm lớn.
  • và tất nhiên, chú thích DI làm cho nó rất rõ ràng khi một lớp phụ thuộc vào một lớp khác, giúp tự viết mã nhiều hơn.
+0

Cảm ơn, Snicolas, Jean-Phillipe. Tôi đã tạm thời thực hiện điều này như là một singleton riêng biệt, nhưng chắc chắn sẽ sử dụng lớp ứng dụng. – Tiger

+1

Giải pháp này sẽ thất bại khi quá trình đăng ký của bạn được khởi động lại và sau đó bạn khôi phục hoạt động cố gắng đọc dữ liệu từ (phổ biến nhất, trong phương thức onCreate) –

+0

@SargeBorsch 'onSaveInstanceState()' có thể lưu trong trường hợp đó! –

0

Chỉ cần để đáp ứng với Snicolas' câu trả lời:

Application đã là một Singleton, không cần phải "biến nó thành" một.

Cá nhân, sau khi một số sự phụ thuộc nghiêm túc vào Ứng dụng để giữ dữ liệu trong một thời gian dài, tôi đã không tin tưởng nó hoàn toàn. Tôi sử dụng các đối tượng dữ liệu tự lưu vào bộ nhớ đệm để giảm thiểu các vấn đề;)

+0

Đã cập nhật, cảm ơn. Tôi hoàn toàn đồng ý với bạn ngay bây giờ. Tôi nghĩ rằng nó vẫn còn tốt để xem xét rằng các ứng dụng là phạm vi quyền để xác định một singleton. Có thể không thích hợp để sử dụng lớp ứng dụng để liên kết chúng với phạm vi ứng dụng. Bây giờ tôi thích 2 mẫu, một trong số chúng như bạn mô tả. Tôi sẽ cập nhật giải pháp của mình để nói về nó. Tôi mời bạn bình luận về nó một lần nữa nếu bạn cảm thấy thích nó. – Snicolas

+0

Hi straya bạn có thể vui lòng cung cấp bất kỳ lý do tại sao không tin tưởng Lớp ứng dụng để giữ dữ liệu? –

+1

@MuhammadBabar vì Ứng dụng có thể được tạo lại bất cứ lúc nào (lý thuyết do bộ nhớ thấp) của hệ điều hành, và bạn sẽ không phải lúc nào cũng nhìn thấy các ứng dụng Application.onTerminate() cũng như Application.onLowMemory(). http://stackoverflow.com/questions/12672584/android-app-application-singleton-instance-gets-recreated – straya