2014-10-27 14 views
10

Tôi đã xem qua nhiều ví dụ/hướng dẫn về cách sử dụng SQLite trong Android. Giả sử bạn có một ứng dụng sử dụng SQLite, ContentProvider, CursorLoader, một tùy chỉnh CursorAdapter. Bây giờ tất cả các ví dụ chính về điều này mà tôi đã tìm thấy dựa trên một số CursorLoader để tìm nạp dữ liệu đến CursorAdapter, theo bản chất của CursorLoader xảy ra trong một chủ đề an toàn Async - UI. Tuy nhiên, những ví dụ tương tự này tất cả đều thực hiện các cuộc gọi chèn/xóa/cập nhật thông qua ContentResolver trên luồng chính (ví dụ: onClick, onResume,). (Example) Chúng không bao bọc các cuộc gọi này trong một số AsyncTask hoặc khởi chạy một chuỗi riêng biệt hoặc sử dụng AsyncQueryHandler. Tại sao điều này, làm thế nào có thể rất nhiều blog/ví dụ được viết cũng tạo nên một sai lầm rõ ràng như vậy? Hoặc đơn giản là chèn/xóa/cập nhật các cuộc gọi đơn giản đến nỗi chúng đủ an toàn để khởi chạy từ luồng chính/giao diện người dùng? Cách thích hợp để thực hiện các cuộc gọi nhanh này là gì?Android - SQLite ContentResolver chèn/xóa/cập nhật trên Giao diện người dùng?

+1

câu cuối cùng của bạn có thể đúng: hoạt động truy vấn chắc chắn phức tạp hơn nhiều so với chèn/cập nhật/xóa – pskink

Trả lời

4

Tôi cũng đã nhầm lẫn về các mẫu thực hiện cuộc gọi trên chuỗi chính. Tôi đoán các mẫu chỉ đơn giản hóa các cuộc biểu tình tránh các chủ đề bổ sung và gọi lại, kể từ khi duy nhất chèn/cập nhật/xóa cuộc gọi có thể trở lại một cách nhanh chóng.

Bên cạnh mẫu Trình tải cho truy vấn, android đã cung cấp lớp trợ giúp AsyncQueryHandler, kể từ API cấp 1, cho các hoạt động CRUD không đồng bộ với các cuộc gọi lại CRUD đầy đủ được hỗ trợ. AsyncQueryHandler làm việc bên trong với một HandlerThread cho các hoạt động không đồng bộ và cung cấp các kết quả về chủ đề chính.

Vì vậy, tôi tin rằng các truy vấn ContentProvider sẽ chạy trong các chuỗi công việc ngoài giao diện người dùng và các mẫu đó có thể không phải là phương pháp hay nhất theo thiết kế chính thức.

=== chỉnh sửa

Tìm thấy một chú thích từ các tài liệu chính thức khuôn khổ, xem this hoặc this, Line 255:

In practice, this should be done in an asynchronous thread instead of 
on the main thread. For more discussion, see Loaders. If you are not 
just reading data but modifying it, see {@link android.content.AsyncQueryHandler}. 

=== chỉnh sửa 2 Link để hướng dẫn dev android thực tế có chứa các trên báo giá

+0

Phải, tôi đã đề cập đến AsyncQueryHandler trong câu hỏi của mình ... vẫn không thuyết phục được TẤT CẢ các hướng dẫn và ví dụ, rằng tôi đã đến qua làm điều này, chỉ vì nó đơn giản hơn và thậm chí không đề cập rằng đây không phải là cách bạn nên làm điều đó. Đối với một câu trả lời thích hợp, tôi muốn một cái gì đó chính thức từ Google (thành viên nhóm, doc, hướng dẫn) hoặc một cái gì đó dọc theo những dòng đó (có thể là một liên kết đến một dự án GitHub đáng kính thực hiện theo cách này hay cách khác). Chủ đề chính, hoặc sử dụng một cái gì đó như AsyncQueryHandler ... –

+0

Nếu không mọi thứ khác chỉ là ý kiến ​​của chúng tôi về điều này ... :) –

+0

@LeoK Có một tài liệu chính thức đề cập đến điều này. Vui lòng xem các chỉnh sửa của tôi. –

2

Câu hỏi này đã xuất hiện trong đầu tôi từ lâu. Tôi đoán, điều này phụ thuộc vào độ phức tạp của tệp mà chúng tôi đang cố gắng Chèn, Cập nhật hoặc Xóa. Nếu ứng dụng của chúng ta sẽ Chèn hoặc Cập nhật các tệp lớn, nó sẽ luôn luôn đúng để làm điều đó một cách không đồng bộ và nếu các tệp sẽ không lớn, chạy nó trên chuỗi giao diện người dùng có thể được thực hiện.

Tuy nhiên, bạn luôn nên tiếp tục với các hoạt động của Cơ sở dữ liệu trên một chuỗi riêng biệt.

+0

Cảm ơn bạn đã trả lời. Điều này không thực sự giải thích đầy đủ lý do tại sao Hướng dẫn giải thích thực tiễn tốt nhất và trong các khía cạnh khác làm những việc đúng/an toàn trong trường hợp chèn/xóa/cập nhật không bao giờ bận tâm với các chủ đề riêng biệt. Rõ ràng là tôi đã không đọc tất cả các hướng dẫn tốt ra khỏi đó để một số ví dụ truy cập tốt sẽ được chào đón. (Đặc biệt là những người từ Google hoặc các nguồn có uy tín khác) –

0

Tôi nghĩ bạn đã trả lời câu hỏi của riêng bạn. Tôi tin rằng CursorLoader mở rộng AsyncTaskLoader. Các cuộc gọi được thực hiện từ chuỗi giao diện người dùng chỉ xử lý cuộc gọi tới trình cắm thêm CusorLoader (sử dụng AsyncTask.) Điều gì đang được thực hiện bởi cuộc gọi vẫn không xảy ra trên UI Thread. Thực hiện cuộc gọi đến một phương thức/chức năng mà sau đó chạy mọi thứ trên một chuỗi riêng biệt vẫn đang làm việc cách xa chuỗi giao diện người dùng.

Bạn nghĩ điều gì đang xảy ra trên chuỗi giao diện người dùng?

Vui lòng hiển thị Nhật ký gỡ lỗi nếu có thể hoặc ví dụ nơi bạn nghĩ rằng công việc được thực hiện trên giao diện người dùng. Không nên.

Không cố gắng tranh luận chỉ muốn biết bạn đã đi đến kết luận của công việc giao diện người dùng như thế nào?

+0

Bạn nói đúng về trình tải con trỏ không đồng bộ. Đây là những gì tôi đã viết bản thân mình trong câu hỏi. Tuy nhiên, việc chèn/xóa/cập nhật cuộc gọi được thực hiện thông qua ContentReslover chứ không phải CursorLoader. Tất cả mọi thứ đi qua ContentReslover được thực hiện trên chuỗi giao diện người dùng, nếu cuộc gọi đến nó được thực hiện trên chuỗi giao diện người dùng. Điều này rất dễ dàng để xác minh đơn giản bằng cách thêm một Thread.sleep (5000) vào đầu chèn ghi đè của ContentProvider của bạn. Nếu bạn làm như vậy, bạn sẽ thấy giao diện người dùng bị đóng băng trong 5 giây ... –

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