6

Tôi có một vấn đề bán phức tạp và hy vọng rằng ai đó ở đây sẽ có thể giúp tôi.Android: thông báoDataSetChanged() không cập nhật listview sau khi thay đổi hướng

Trên sự kiện nhấp, tôi tạo một chuỗi và bắt đầu một hoạt động lâu dài dựa trên phương pháp this. Sau khi nhiệm vụ kéo dài được hoàn thành, nó hoạt động gọi lại phương pháp khác, mà hiện một đường bưu điện đến xử lý:

@Override 
public void contentSearchModelChanged(Model_ContentSearch csm, ArrayList<Class_Reminder> newRemindersList) { 
    remindersList = newRemindersList; 
    mHandler.post(mUpdateDisplayRunnable); 
} 

nào gọi một Runnable:

// post this to the Handler when the background thread completes 
private final Runnable mUpdateDisplayRunnable = new Runnable() { 
    public void run() { 
    updateDisplay(); 
    } 
}; 

Cuối cùng, đây là những gì tôi Phương thức updateDisplay() đang thực hiện:

private void updateDisplay() { 
    if (csModel.getState() != Model_ContentSearch.State.RUNNING) { 
     if(remindersList != null && remindersList.size() > 0){ 
       r_adapter = new ReminderAdapater(Activity_ContentSearch.this, remindersList, thisListView); 
       thisListView.setAdapter(r_adapter); 
       r_adapter.notifyDataSetChanged(); 
     } 
    } 
} 

Điều này làm việc tốt khi tôi làm điều này bình thường. Tuy nhiên, nếu tôi thay đổi hướng trong khi hoạt động dài hạn đang chạy, nó sẽ không hoạt động. Nó làm cho gọi lại đúng cách, và các remindersList không có các mục trong đó. Nhưng khi đến dòng này:

r_adapter.notifyDataSetChanged(); 

Không có gì xảy ra. Điều kỳ lạ là, nếu tôi gửi một lần nữa và để nó chạy toàn bộ quá trình một lần nữa (không thay đổi hướng), nó thực sự cập nhật lượt xem hai lần, một lần cho lần gửi trước đó và lần nữa cho lần tiếp theo. Vì vậy, lượt xem cập nhật một lần với kết quả của lần gửi đầu tiên, sau đó lại với kết quả của lần gửi thứ hai sau một giây. Vì vậy, các adapater DID có được dữ liệu, nó chỉ là không làm mới xem.

Tôi biết điều này có liên quan đến sự thay đổi định hướng, nhưng tôi không thể cho cuộc sống của tôi tìm ra lý do. Có ai giúp được không? Hoặc, bất cứ ai có thể đề xuất một phương pháp thay thế xử lý các chủ đề với những thay đổi định hướng?

Bara

Trả lời

6

Vấn đề là khi bạn thay đổi hướng hoạt động mới được tách ra từ đầu (onCreate). Quá trình chạy dài của bạn có thể xử lý hoạt động cũ (không còn nhìn thấy được). Bạn đang cập nhật đúng hoạt động cũ nhưng vì nó không còn trên màn hình nữa nên bạn không nhìn thấy nó.

Đây không phải là vấn đề dễ khắc phục. Có một thư viện ở đó có thể giúp bạn mặc dù. Nó được gọi là DroidFu. Đây là một bài viết trên blog rằng (nhiều hơn một cách chính xác hơn là tôi) mô tả nguyên nhân gốc rễ của những gì bạn đang nhìn thấy và làm thế nào các thư viện DroidFu combats nó: http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/

Edit: (Thêm mã để theo dõi hoạt động hoạt động)

Trong lớp ứng dụng của bạn thêm này:

private Activity _activeActivity; 
public void setActiveActivity(Activity activity) { 
    _activeActivity = activity; 
} 
public Activity getActiveActivity() { 
    return _activeActivity; 
} 

Trong hoạt động của bạn, thêm này:

@Override 
public void onResume() { 
    super.onResume(); 
    ((MyApplicationClassName)getApplication()).setActiveActivity(this); 
} 

Bây giờ bạn có thể nhận được activi tích cực ty bằng cách gọi MyApplicationClassName.getActiveActivity();

Đây không phải là cách DroidFu thực hiện. DroidFu đặt hoạt động tích cực trong onCreate nhưng tôi không cảm thấy điều đó rất mạnh mẽ.

+0

Hmm ... có vẻ rất hữu ích, nhưng dường như không có nhiều tài liệu? Tôi ghét phải thay đổi việc triển khai của mình để sử dụng DroidFu và không biết cách giải quyết vấn đề vì đó không phải là cách làm "điển hình". – Bara

+0

Vâng, nó có vẻ là một thư viện bị bỏ hoang cũ nhưng tiền đề dường như là âm thanh. Bạn có thể làm điều này mà không cần sử dụng thư viện. Về cơ bản đối tượng Application theo dõi hoạt động đang hoạt động (sử dụng onResume). Sau đó, khi bạn đã sẵn sàng thông báo cho bộ điều hợp của mình, bạn sẽ nhận được Hoạt động hoạt động từ Ứng dụng, kiểm tra xem đó có phải là một hoạt động dự kiến ​​của bạn hay không và nếu có, truyền và thông báo. –

+0

Mã chính xác để theo dõi "Hoạt động hoạt động" là gì? Đó là, tôi nên làm một cái gì đó như CurrentActivity act = new CurrentActivity(); sau đó chuyển hành động đến lớp Ứng dụng? – Bara

1

Tôi đã có một vấn đề tương tự, có một thời gian gửi thread sendEmptyMessage đến một trình xử lý, mà lần lượt được gọi là notifyDataSetChanged trên một ListAdapter. Nó hoạt động tốt cho đến khi tôi thay đổi hướng.

Tôi đã giải quyết nó bằng cách khai báo một trình xử lý thứ hai trong chuỗi giao diện người dùng và tạo trình xử lý đầu tiên sendEmptyMessage cho trình xử lý này, lần lượt được gọi là notifyDataSetChanged trên ListAdapter. Và có ListAdapter được khai báo là tĩnh.

Tôi là một newbie vì vậy tôi không biết nếu nó là một giải pháp xấu xí, nhưng nó làm việc cho tôi ...

Từ mô tả Jere.Jones tôi sẽ giả định làm việc này như sau: Quá trình chạy dài sendEmptyMessage đến tay cầm từ Activity cũ, mà đến lượt sendEmptyMessage đến tay cầm trong Activity mới.

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