2013-02-21 27 views
13

Đây là tình hình của tôi:onCreateView() đợi AsyncTask thực thi?

Trong onCreate() của tôi, tôi muốn tạo một AsyncTask để lấy dữ liệu cho một máy chủ và lưu trữ nó trong một ArrayList.

Sau đó, trong onCreateView() của tôi, tôi muốn đưa dữ liệu trong một ListView, thiết lập một onItemClickListener, vv ...

Vấn đề là tôi đang tạo ra một cuộc chạy đua giữa các AsyncTask và thread UI. Nếu onCreateView() được gọi trước khi AsyncTask được thực hiện lấy, sau đó tôi không đặt bộ chuyển đổi một cách chính xác, không đặt các onItemClickListener, vv ...

Tôi muốn một số cách để đảm bảo rằng tôi chờ cho AsyncTask để hoàn thành thực hiện trước khi bắt đầu chức năng onCreateView(). Điều này có thể không? Tôi đọc về việc sử dụng get() về tác vụ này, nhưng tôi đã gặp một số sự cố khi thực hiện tác vụ đó. Nó dường như không làm gì cả.

Lý do tôi muốn lấy lại dữ liệu trong onCreate() và thiết lập adapter trong onCreateView() (thay vì thiết lập adapter trong onPostExecute() của AsyncTask), là tôi muốn lấy lại dữ liệu một lần, và có thể chỉ cần tạo chế độ xem nếu người dùng xoay màn hình hoặc điều hướng trở lại màn hình đó Fragment.

Trả lời

10

Đây là một cách tốt hơn. Khởi tạo ListView của bạn và bắt đầu AsyncTask trong onCreate(). Khi dữ liệu có sẵn từ máy chủ, bạn thêm nó vào cùng một mảng đã được cung cấp cho bộ điều hợp của bạn và gọi notifyDatasetChanged() của bộ điều hợp của bạn, điều này sẽ đảm bảo việc hiển thị chế độ xem danh sách của bạn. Tại đây bạn có thể sử dụng ListFragment cũng như trong đó bạn có thể gọi setEmptyText() để thêm văn bản được hiển thị nếu danh sách của bạn trống.

+0

oh thú vị.Tôi có phải setOnItemClickListener() mỗi lần tôi cập nhật bộ điều hợp không? hoặc chỉ một lần ngay từ đầu? Ngoài ra, làm thế nào tôi có thể khởi tạo listview trong onCreate() nếu xem chưa được tạo chưa? điều đó sẽ không cho tôi một sự nhận biết nullpointerexception? – user2085335

+0

bạn phải đặt 'OnItemClickListenter' chỉ một lần. Để khởi tạo chế độ xem danh sách khi không có dữ liệu, chỉ cần sử dụng 'ArrayList' không có phần tử. Nó sẽ không đưa ra bất kỳ NullPointerException nào. Sau đó khi dữ liệu đến, bạn có thể thêm nó vào cùng một 'ArrayList' và gọi' notifyDataSetChanged() '. – sujith

+0

cảm ơn! hoạt động tuyệt vời! một câu hỏi nhanh về nhận xét 'OnItemClickListener': Nếu tôi chỉ có lệnh gọi' setOnItemClickListener' trong 'onCreateView()', nó dường như không hoạt động. Nhưng nếu tôi thêm một cuộc gọi khác để 'setOnItemClickListener' sau khi tôi cập nhật bộ điều hợp, nó hoạt động. Đây không thực sự là một vấn đề lớn vì nó đang hoạt động theo cách này, nhưng tôi muốn biết tại sao điều này có thể xảy ra nếu bạn có bất kỳ ý tưởng nào. Cảm ơn bạn. – user2085335

0

Dù bạn đang làm trong onCreateView(), di chuyển nó đến onViewCreated()

onViewCreated được gọi sau khi xem đã sẵn sàng, do đó bạn sẽ không có vấn đề rồi

1

Bạn nên làm theo câu trả lời @ Sujith và thay đổi thực hiện của bạn, nhưng đây là một câu trả lời cho câu hỏi cụ thể của bạn:

Tôi muốn một số cách để đảm bảo rằng tôi chờ cho AsyncTask để kết thúc thực hiện trước bắt đầu hàm onCreateView(). Đây có phải là không?

Có điều này là có thể, nhưng nó sẽ ngăn giao diện người dùng của bạn hiển thị trong khi chờ tác vụ kết thúc.

Tạo và thực hiện AsyncTask của bạn sau đó giữ cho tham chiếu đến nó:

MyAsyncTask mTask; 

... 
...onCreate() 
mTask = new MyAsyncTask(); 
mTask.execute(); 
... 
...onCreateView() 
myInfo = mTask.get(); 
super.onCreateView(). 

Trong trường hợp của bạn này là một ý tưởng tồi, tuy nhiên, có những lúc bạn có thể cần phải làm một cái gì đó như thế này.

EDIT: mTask.get() sẽ trở lại bất cứ điều gì được trả về bởi các doInBackground()

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