2012-04-11 21 views
6

Tôi muốn biết cách sử dụng CursorLoader để điền các widget trên màn hình. Tất cả các ví dụ trực tuyến chỉ dành cho việc sử dụng bộ điều hợp và công trình này tuyệt vời. Những gì tôi cần là một cách đáng tin cậy để cập nhật các chế độ xem trong màn hình của tôi từ một Con trỏ và trên chuỗi giao diện người dùng và đôi khi không bị rơi do StaleDataException hoặc con trỏ bị vô hiệu hóa đột ngột. Đây là cách tiếp cận hiện tại của tôi nhưng tôi vẫn nhận được một số báo cáo sự cố từ người dùng.Điền các widget từ một con trỏ trong onLoadFinished()

@Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle arg1) { 
     CursorLoader loader = null; 

     switch (id) { 
      case LOADER_ID_DATA: 
       loader = new CursorLoader(...); 
       break; 
     } 

     return loader; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, final Cursor cursor) { 
     handler.post(new Runnable() { 

      @Override 
      public void run() { 
       if (getActivity() == null) 
        return; 

       updateView(cursor); 
      } 
     }); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> arg0) { 
    } 

Một giải pháp sẽ là truy xuất tất cả các trường con trỏ trực tiếp bên trongLoadFinished và chuyển tất cả đến trình xử lý để điền các tiện ích vào chuỗi giao diện người dùng. Nhưng điều này là xấu bởi vì tôi có thể có rất nhiều giá trị trong con trỏ. Tôi rất thích tìm một cách không gặp sự cố đáng tin cậy để giải quyết tất cả những điều này.

+0

"Một giải pháp là lấy tất cả các trường con trỏ trực tiếp bên trong onLoadFinished và chuyển tất cả chúng tới trình xử lý để điền các tiện ích vào chuỗi giao diện người dùng" - 'onLoadFinished()' được gọi trên chuỗi ứng dụng chính. – CommonsWare

+0

@CommonsWare Theo như tôi biết, onLoadFinished không được gọi trên luồng giao diện người dùng chính. Nếu bạn tìm kiếm ví dụ tại mã nguồn android-protips_location được viết bởi Reto Meier, anh ta sử dụng trình xử lý để điền các tiện ích con với các giá trị. Và bình luận của anh ta ở trên onLoadFinished() là anh ta lên lịch cập nhật về luồng ứng dụng chính. –

+0

Trích dẫn từ Reto Meier: "Lưu ý rằng onLoadFinished không được đồng bộ hóa với chuỗi ứng dụng chính, vì vậy tôi trích xuất các giá trị Cursor trên cùng một luồng như Con trỏ đã được tải, trước khi đăng một Runnable mới vào thread UI gán giá trị cho các thành phần giao diện người dùng " –

Trả lời

7

Sau khi yêu cầu # android-dev SimonVTreadme đã giúp tôi nhận được thông tin này.

Không có gì tuyên bố rằng onLoadFinished sẽ được gọi trên chuỗi giao diện người dùng, vì vậy theo lý thuyết bạn nên sử dụng Handler như được khuyên trong sách của Reto. Tuy nhiên, khi sử dụng CursorLoader (trường hợp này là trường hợp sử dụng phổ biến nhất), bạn có thể đảm bảo rằng onLoadFinished sẽ được gọi trong chuỗi giao diện người dùng.

+3

Lý do cho "khá nhiều" là CursorLoader sử dụng AsyncTask để thực hiện công việc nền của nó, sử dụng trình xử lý tĩnh để đăng lại và cuối cùng gọi onLoadFinished. Nếu bạn gọi LoaderManager.initLoader (...) từ luồng chính, thì trình xử lý cũng được đảm bảo để gắn vào luồng chính. Đối với trình điều khiển này không được gắn vào luồng chính, bạn phải tạo một Thread với một Looper, và khởi động Loader từ đó. – SimonVT

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