Tôi có một luồng riêng chạy để lấy dữ liệu từ internet. Sau đó, tôi muốn cập nhật ListView trong thread chính bằng cách gọi adapter.notifyDataSetChanged(). Nhưng nó không hoạt động. Bất kỳ cách giải quyết nào cho điều đó? Cảm ơn.Cập nhật ListView trong chuỗi chính từ một chủ đề khác
Trả lời
Sử dụng AsyncTask (http://developer.android.com/reference/android/os/AsyncTask.html).
Gọi adapter.notifyDataSetChanged() trong phương thức onPostExecute (...).
Để biết thêm chi tiết, vui lòng đọc này: http://android-developers.blogspot.com/2009/05/painless-threading.html
Nhìn chung lời khuyên tốt là http://android-developers.blogspot.com/2009/05/painless-threading.html
Cá nhân tôi sử dụng chủ đề tùy chỉnh của tôi (một lớp mở rộng chủ đề) nhưng gửi thư trả lời đến thread UI thông qua một tin nhắn. Vì vậy, trong hàm run() của luồng có:
Message msg;
msg = Message.obtain();
msg.what = MSG_IMG_SET;
mExtHandler.sendMessage(msg);
Chuỗi giao diện người dùng xác định trình xử lý tin nhắn.
private Handler mImagesProgressHandler;
public void onCreate(Bundle bundle) {
mImagesProgressHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LoadImagesThread.MSG_IMG_SET:
mArrayAdapter.setBitmapList(mImagesList);
mArrayAdapter.notifyDataSetChanged();
break;
case LoadImagesThread.MSG_ERROR:
break;
}
super.handleMessage(msg);
}
};
Điều này thực sự dễ dàng hơn so với AsyncTask.
Tôi thích phương pháp này cũng như – Mark
Tôi quên đề cập: bạn cũng có thể thêm đối tượng vào thông báo như: msg.obj = someBitmap; và nhận nó trong trình xử lý (ví dụ như có thể cập nhật một mảng hoặc danh sách với bitmap đã nhận và thông báo cho bộ điều hợp rằng dữ liệu cơ bản của danh sách đã thay đổi: mArrayAdapter.notifyDataSetChanged();). Trong trường hợp này, không có điều kiện chủng tộc nào có thể xảy ra. – Yar
Hãy coi chừng - Đây là những con rồng! Lớp bên trong Handler này có một tham chiếu ngầm tới lớp bên ngoài 'this. Tốt hơn để làm cho Handler đó tĩnh và nhận một WeakReference đến lớp bên ngoài. –
Hoặc, gửi một thông điệp tới hàng đợi thông điệp của listview (trong đó sẽ thực hiện trên thread UI):
list.post(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
Giả yourActivity
là hoạt động mà widget của bạn đã được đặt vào nó, yourView
là The phụ tùng và adapter
là bộ chuyển đổi của phụ tùng:
yourActivity.runOnUiThread(new Runnable() {
public void run() {
try{
adapter.notifyDataSetChanged();
}
catch{}
}
}
Bạn có thể sử dụng một sự kết hợp của RxJava và Retrofit cho mục đích này.
Đây là cách bạn có thể thực hiện. Tôi sẽ sử dụng API GitHub cho ví dụ.
Tạo giao diện Java cho API HTTP của bạn.
public interface GitHubService {
@GET("users/{user}/repos")
Observable<List<Repo>> listRepos(@Path("user") String user);
}
Sử dụng Observable sẽ chuyển đổi phản hồi thành luồng. Mỗi sự kiện là một Danh sách các Repos.
Sử dụng lớp Retrofit để tạo triển khai giao diện GitHubService. Bạn có thể hoặc có thể hoặc không thể cung cấp một HTTP Client tùy chỉnh.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.client(okHttpClient) // OkHttp Client
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
Bây giờ đến phần Rx. Bạn phải thêm người đăng ký để nghe các phản hồi do máy chủ gửi lại. Nói cách khác, phản ứng với nó.
service.listRepos("octocat")
.subscribeOn(Schedulers.io()) // 1
.observeOn(AndroidSchedulers.mainThread()) // 2
.flatMap(Observable::from) // 3
.subscribe(repoList -> { // 4
// Update the list view
// notifyDataSetChanged
});
Đây là những gì các dòng chú giải với những con số đang làm -
1 - Nó nói với hệ điều hành mà thread được sử dụng để thực hiện cuộc gọi. Chúng tôi đang lựa chọn các thread IO cho điều đó.
2 - Nó cho biết hệ điều hành nào sẽ được sử dụng để nghe câu trả lời. Chúng tôi làm điều đó trên chuỗi chính và cập nhật giao diện người dùng khi nhận được phản hồi.
3 - Dòng này thể hiện sự kỳ diệu thực sự của Rx. Dòng đơn giản này chuyển đổi một danh sách các câu trả lời cho các đối tượng đơn lẻ. Do đó chúng tôi sẽ phản ứng với mọi đối tượng thay vì toàn bộ danh sách. Bạn có thể đọc thêm về nó here.
4 - Dòng này thực sự xác định loại 'phản ứng' nào sẽ được hiển thị cho sự kiện. Bạn có thể cập nhật bộ điều hợp tại đây.
Một thuê bao phức tạp hơn trông như thế này -
new Subscriber<Repo>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Repo repo) {
}
}
T.B. - Tôi đã sử dụng lambdas trong các ví dụ trên. Bạn có thể thêm điều đó thông qua here.
Bí quyết ở đây là vị trí nơi bạn đặt các
mAdapter.notifyDataSetChanged();
Dưới đây là một ví dụ đơn giản:
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
mAdapter = new myAdapter(......);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
tác phẩm này với tôi một cách hoàn hảo.
- 1. Cập nhật nhãn từ một chủ đề khác
- 2. Cập nhật một ObservableCollection từ một chủ đề khác
- 3. Android: Cập nhật Listview sau khi Chủ đề tải dữ liệu từ mạng
- 4. GUI không được cập nhật từ một chủ đề khác khi sử dụng PyGtk
- 5. Cách cập nhật hộp văn bản trên GUI từ một chủ đề khác
- 6. Cập nhật WPF ràng buộc trong một chủ đề nền
- 7. PySide: Cách dễ dàng hơn để cập nhật GUI từ một chủ đề khác
- 8. Chủ đề ngủ từ một số khác
- 9. ListView Đang cập nhật một hàng
- 10. ListView không được cập nhật chính xác với ObservableCollection
- 11. JavaFX: Đang cập nhật phần UI trong một lớp điều khiển từ một chủ đề
- 12. Biến truy cập từ một lớp khác từ một chủ đề
- 13. Cập nhật GUI (WPF) bằng cách sử dụng một chủ đề khác
- 14. Cập nhật giá trị tối đa từ nhiều chủ đề
- 15. C# - Cập nhật một subitem trong một listview
- 16. Cập nhật tổng thể cục bộ cho chủ từ xa từ một chi nhánh khác
- 17. Android Listview không cập nhật
- 18. Viết cho một TextBox từ một chủ đề khác?
- 19. CoreData: cập nhật trong nền và đọc trong chủ đề chính gây ra khóa chết
- 20. Chủ đề WPF và GUI cách truy cập đối tượng từ chuỗi khác nhau?
- 21. Cập nhật một listview trong một đoạn từ một máy thu phát sóng
- 22. Cập nhật chủ đề wordpress trên ec2
- 23. Đã cố gắng lấy khóa web từ một chủ đề khác với chuỗi chính hoặc chuỗi web. Lỗi hiện tại
- 24. Truy cập các giao diện từ chủ đề khác (Android)
- 25. BaseAdapter.notifyDatasetChanged() không cập nhật ListView
- 26. Chạy điều khiển WPF trong một chủ đề khác
- 27. Tại sao không thể cập nhật ObservableCollection từ một chuỗi khác?
- 28. Chủ đề chính sẽ bị loại trừ bởi một chuỗi khác?
- 29. Cách cập nhật giao diện người dùng từ một chuỗi khác đang chạy trong một lớp khác
- 30. Làm cách nào để cập nhật ListView khi cuộn trong khi truy xuất dữ liệu từ máy chủ trong Android?
http://stackoverflow.com/a/33584826/1318946 –