2012-02-17 62 views
5

Gần đây, tôi đã gặp phải một số vấn đề với android.os.Bundle mà tôi hy vọng khắc phục bằng cách đơn giản mở rộng lớp học và làm cho nó được nhập gọn hơn. Các vấn đề cụ thể mà tôi chạy vào là lỗi như:Tại sao android.os.Bundle là một lớp học cuối cùng?

W/Bundle (6782): Key access_token expected byte[] but value was a java.lang.String. The default value <null> was returned. 
W/Bundle (6782): Attempt to cast generated internal exception: 
W/Bundle (6782): java.lang.ClassCastException: java.lang.String 
W/Bundle (6782): at android.os.Bundle.getByteArray(Bundle.java:1305) 

Tất nhiên, chuyển đổi từ String để byte[] là tầm thường, vì vậy suy nghĩ của tôi là chỉ có các Bundle tự động làm chuyển đổi này nếu nó tìm kiếm một byte[] nhưng thấy thay vào đó, hãy thay thế một số String. Thật ngớ ngẩn khi nó không thực hiện điều này (và cũng có các getters và setters cụ thể cho khá nhiều mỗi loại nguyên thủy và một vài loại khác nhau Object thay vì loại chung chung chỉ hoạt động theo số Object hoặc ít nhất là Number , StringParcelable), theo ý kiến ​​của tôi.

Nhưng dù sao, tôi nhanh chóng phát hiện ra rằng tôi không thể khắc phục sự cố bằng cách mở rộng Bundle, bởi vì nó được khai báo final. Có bất kỳ lý do đã biết/cụ thể nào cho điều này không? Có các lớp khác trong số android.os không phải là final, vì vậy điều gì làm cho Bundle xứng đáng với việc gán này?

Ngoài ra, có ý tưởng nào về cách giải quyết vấn đề này không? Lớp bao bọc là không có interface phổ biến để nó triển khai (mã thực sự gây ra sự cố là một phần của thư viện của bên thứ ba, vì vậy tôi không thể cập nhật nó để tham chiếu trực tiếp đến lớp trình bao bọc).

Tôi đoán rằng để nguyên tùy chọn duy nhất tìm kiếm tất cả các vị trí trong mã xảy ra để thiết lập các giá trị String cho những thứ mà mã của bên thứ ba dự kiến ​​được chuyển thành mảng byte.

+2

Có lẽ vì lý do tương tự Nhật ký là cuối cùng: để piss bạn ra. – AedonEtLIRA

+0

Trong chuyển đổi C# thế giới từ chuỗi thành byte [] là tầm thường, nhưng không rõ ràng (ví dụ: Convert.FromBase64String hoặc Encoding.Utf8.GetBytes hoặc một số mã hóa khác). Java có chuyển đổi String-> byte [] chính thức không? –

+0

@Alexei Levenkov - Có, Java có [String.getBytes()] (http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#getBytes()). – aroth

Trả lời

1

Về cơ bản, tất cả các loại "nguyên thủy" là cuối cùng. Có một vài lý do cho việc này. Đầu tiên, gói có nghĩa là để được parceable và bạn có thể phá vỡ một số nếu ngữ nghĩa của nó bằng cách ghi đè. Ngoài ra, Bundle có nghĩa là luôn luôn hành động theo một cách nhất định. Nếu bạn ghi đè nó, bạn có thể thay đổi hành vi mà mọi người đang mong đợi hoặc thậm chí ném một mã vi phạm ngoại lệ được coi là an toàn trước đó.Nó cũng có thể được lập luận rằng nó sẽ là một lỗ hổng bảo mật để cho phép nó vì họ có thể ghi đè lên nó với mã có thể theo dõi những gì đã xảy ra với nó.

0

Nếu bạn có một Chuỗi bạn muốn truyền dưới dạng mảng byte và bạn không muốn xử lý tác vụ đó bên ngoài Gói, bạn sẽ làm như thế nào?

Bundle.putByteArray(String string) <<== ?? 

Bạn đã có putByteArray() mà các cửa hàng một ByteArray, và putString() mà các cửa hàng một String ... như bạn nói, việc chuyển đổi là tầm thường, vì vậy nếu bạn cần phải có một String như một ByteArray, tại sao không chỉ cần thực hiện chuyển đổi trước khi bạn đặt nó trong nhóm và chuyển đổi lại khi bạn kéo nó ra?

Vì lý do tại sao lớp học là cuối cùng, bạn đã xác định rằng nó xử lý "mỗi loại nguyên thủy và một vài loại khác nhau Object", vậy tại sao lại tăng số lượng lớp học không cần thiết? Có sự tiện lợi và sau đó có dự phòng ...

+1

Huh? Làm thế nào để khai báo lớp 'final' giảm cruft? Đối với một lớp học là một phần của SDK được dự kiến ​​sẽ được hàng trăm nghìn người sử dụng, không phải hàng triệu nhà phát triển, tôi hy vọng các kiến ​​trúc sư SDK sẽ rất miễn cưỡng để làm cho lớp * bất kỳ *, vì khó dự đoán mọi thứ mà tất cả những người phát triển có thể muốn làm. – aroth

+0

Hãy nhớ ... chúng ta đang nói về Bundle, một lớp kiểu từ điển chỉ đơn giản là dự định gói dữ liệu để truyền tải. Thật sự rất khó để đoán trước mọi thứ mà hàng triệu nhà phát triển có thể muốn làm, nhưng tôi có thể tưởng tượng họ đang tiêu tốn hầu hết năng lượng của họ để dự đoán mọi thứ mà hàng triệu nhà phát triển có thể cần phải làm. Nếu thực sự quan trọng đối với bạn, tôi khuyên bạn nên gửi yêu cầu thay đổi SDK. –

0

Lớp học cuối cùng vì bạn không nên NEED để kế thừa. The documentation cho thấy rằng có rất nhiều phương pháp cho get ing và put ing tất cả các loại. Nếu bạn thực sự lo ngại về việc chuyển đổi một String thành một số byte[], thì những gì bạn đang tìm kiếm là một phương pháp Java (click me) và không phải là một thứ gì đó độc đáo đối với Android.

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