2012-10-11 31 views
5

Trong ứng dụng của tôi, tôi cần rất nhiều nội dung CRUD: đọc bản ghi từ cơ sở dữ liệu SQLite cục bộ, chèn đối tượng và cập nhật nội dung. Hầu hết các truy vấn đơn giản đến mức chúng sẽ không chặn ngay cả khi chạy trên chuỗi giao diện người dùng, tuy nhiên trong ứng dụng này tôi muốn áp dụng mẫu Windows Phone: hoạt ảnh bắt đầu immediatelty và trong hoạt ảnh bắt đầu khi kết quả được phân phối.Khung tải so với đồng bộ AsyncTask

Tôi dự định sử dụng AsyncTask cho công việc, tuy nhiên tôi nhận thấy rằng Honeycomb (và gói compat) giới thiệu khung Tải mới. Ưu điểm chính có vẻ như dữ liệu được tải bởi một thay đổi cấu hình tồn tại Loader. Dự án LoaderEx bởi các cầu nối Commonsware giữa SQLite và khung công tác, nhưng một số vấn đề nảy sinh.

  1. Tài dọn dẹp: Tôi sử dụng một hoạt động đơn lẻ, tạo SQLiteOpenHelper trong onCreate() và đóng nó onDestroy(). Vì trình quản lý bộ nạp có thể vẫn đang chạy, tôi kiểm tra nó và đặt cờ pendingClose trên đối tượng gọi lại của tôi, vì vậy nó sẽ đóng con trỏ và trình trợ giúp khi tải xong. Tôi nghĩ rằng không phải đóng cơ sở dữ liệu không có hại, nhưng SQLite than phiền nếu bạn không làm điều đó, và tôi không thích thông báo lỗi :) Điểm ở đây là dữ liệu không tồn tại thay đổi cấu hình. vanishes

  2. Tôi nên tạo bao nhiêu trình tải? Giả sử tôi có các bảng CustomerOrder được yêu thích. Trình tải được xác định bởi ID giống như CUST_L hoặc ORD_L, nhưng mỗi lần người dùng nhấp vào một số tóm tắt, tôi muốn đưa vào màn hình với chi tiết. Tôi có nên restart trình tải với các thông số khác nhau hay tôi nên init một trình kích hoạt mới có ID ngẫu nhiên? Điều này có thể xảy ra hàng chục lần. Khung tải có dành cho nhiều công việc nhỏ đang chạy hay chỉ cho một vài tác vụ chạy dài không?

  3. Mục đích của việc sử dụng ID ở bên trong giao diện LoaderCallbacks là gì? Tại sao không đơn giản initLoader(params, callback)? Tôi không nghĩ rằng người ta có thể tái sử dụng một số đoạn logic bên trong một cuộc gọi lại: cuối cùng anh ta sẽ chi nhánh (với if-else hoặc switch trên ID) vì vậy tôi không hiểu điểm đưa ra một định danh cho đối tượng callbacks, thay vì một cách tiếp cận ngây thơ một cuộc gọi lại cho mỗi hoạt động.

Tôi hỏi điều này vì toàn bộ khuôn khổ dường như đã vượt qua tôi và không có tiện ích thực sự. Tôi không hiểu điểm tập trung mã với số LoaderManager và tôi không thể thấy bất kỳ cơ hội mới nào AsyncTask không cung cấp.

Điểm giành chiến thắng duy nhất là thay đổi cấu hình, nhưng tôi không thể khai thác nó do dọn dẹp tài nguyên và tôi không thể tìm ra cách thay thế để đóng SQLiteOpenHelper vì (khá rõ ràng) SQLiteCursorLoader yêu cầu nó nhưng sạch nó lên tùy thuộc vào người dùng. Vì vậy, AsyncTask có vẻ là sự lựa chọn chiến thắng ở đây, nhưng có lẽ tôi đang thiếu một cái gì đó.

+2

"Tôi hỏi điều này vì toàn bộ khuôn khổ dường như đã vượt qua tôi và không có tiện ích thực sự". - Tôi không biết về "overengineered", nhưng cá nhân, tôi chỉ sử dụng 'AsyncTask'. Tôi đã tạo ra 'LoaderEx' để minh họa cách tạo ra các triển khai' Loader' thay thế, nhưng ngay sau khi phát hành nó, tôi kết luận rằng 'Loader' khó chịu hơn nó đáng giá. Ngoại lệ duy nhất sẽ là nếu bạn đã hoàn toàn đi với 'ContentProvider' và có thể sử dụng' CursorLoader', trong trường hợp này tôi là ambivalent về việc sử dụng nó thay vì 'AsyncTask'. – CommonsWare

+1

Vì vậy, về cơ bản bạn đồng ý với các giả định của tôi? Tôi có phạm sai lầm gì trong lý luận của tôi không? – Raffaele

+0

"Vì vậy, về cơ bản bạn đồng ý với các giả định của tôi?" - đối với # 1, trong khi tôi đồng ý sẽ đóng cơ sở dữ liệu, hãy nhớ rằng điều này không bao giờ xảy ra nếu bạn sử dụng mặt tiền 'ContentProvider' xung quanh cơ sở dữ liệu, vì vậy thực tế là khung' Loader' trung tâm 'ContentProvider' không nhất thiết làm cho điều này dễ dàng là không đáng ngạc nhiên. Đối với # 2, tôi không thể đồng ý hay không đồng ý, khi bạn hỏi một câu hỏi thay vì nêu một ý kiến, và tôi không có câu trả lời. Đối với # 3, tôi không đồng ý hoặc không đồng ý, vì tôi đã không đưa ra cách tiếp cận của bạn nhiều suy nghĩ, như tôi không sử dụng 'Loader' cho nhiều. – CommonsWare

Trả lời

4
  1. Nhà cung cấp nội dung mạnh hơn nhiều so với phương pháp "nguyên-DB". Rất nhiều liên kết trên stackoverflow dẫn đến các cuộc thảo luận về điều này.
  2. Trình quản lý tải cố gắng phân biệt các trình tải theo ID của chúng (vì sao chữ ký của initLoader chỉ định đối số này).ID cho trình tải là cần thiết để cung cấp lại kết quả được lưu trong bộ nhớ cache trong trường hợp nếu dữ liệu cho bộ nạp có ID cụ thể đã tồn tại (do đó không cần phải tải lại không đồng bộ).
  3. restartLoader force LoaderManager để bắt đầu quá trình chọn không đồng bộ được chỉ định bởi trình tải được tạo trước đây. initLoader cố gắng sử dụng lại bộ tải hiện có trước khi tạo bộ tải mới.
  4. Các mảnh vỡ và hoạt động có Trình quản lý tải của riêng chúng không trùng lặp.

Trải nghiệm của tôi cho thấy rằng mặc dù sử dụng Nhà cung cấp nội dung có vẻ quá cần thiết để thực hiện, nhưng nó thực sự trả tiền khá tốt trong tương lai. Hiệu suất hit là không đáng kể (đã thử đo nó), UI-Data bindings được thêm vào hộp (vì người quan sát nội dung và CursorLoaders có thể đăng ký thông báo Uri), đồng bộ được thực hiện bởi framework thông qua bộ tải. IMHO, bất cứ khi nào cơ sở dữ liệu là cần thiết, sử dụng nhà cung cấp nội dung với bộ nạp hầu hết các lần là giải pháp tốt nhất mà bạn có thể đưa ra.

Các tình huống khác liên quan đến việc sử dụng cơ sở dữ liệu trực tiếp, sẽ buộc bạn phải thực hiện mọi thứ theo cách thủ công.

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