AsyncTask
là một tác vụ không đồng bộ có nghĩa là bạn thường không biết khi nào công việc được hoàn thành và khi nó gọi onPostExecute()
. Tôi nghĩ rằng vấn đề của bạn là ở đây. Khi bạn xoay thiết bị của mình, asynctask vẫn chưa hoàn thành và khung nhìn phân mảnh của bạn bị hủy và tái tạo lại rất nhanh trong khi asynctask vẫn còn trên luồng công nhân và khi nó thực hiện công việc, đoạn của bạn có một khung nhìn và giá trị trả về của getView
không phải là null
. Nhưng nếu thời gian quay mất nhiều, bạn sẽ nhận được null
vì AsyncTask
đã hoàn tất nhưng đoạn của bạn không có bất kỳ chế độ xem nào. Bây giờ kịch bản này là chính xác xảy ra với backstack của bạn Khi bạn đẩy mảnh của bạn trên để backstack xem của nó bị phá hủy (look at the picture) nhưng bản thân mảnh không phải là (fragment trả về bố trí từ backstack). Bây giờ, hãy hoàn tất AsyncTask
và gọi phương thức fragment
getView
của bạn và liều đó không có bất kỳ view
để bạn sẽ nhận được NPE
.
Giải pháp của tôi:
Trước tiên, bạn nên sử dụng WeakReference<ProgressBar>
thay vì WeakReference<MyFragment>
và trong onPostExecute()
kiểm tra cho dù đó là null hay không, nếu nó là null không làm gì cả vì giá trị mặc định là vô hình nếu nó không phải là null gọi setVisibility(View.GONE)
.
Cập nhật:
đoạn là còn sống nhưng quan điểm đã được dealloc'd. Đây có phải là không?
Có, chỉ cần nhìn vào hình 2 từ liên kết. Khi đoạn đang hoạt động (hộp màu xanh lá cây) the fragment added to back stack
mảnh đi đến , onStop
onDestroyView. Sau đó, khi mảnh vỡ bật lên từ phía sau ngăn xếp nó đi ngay đến onCreateView
liên kết mũi tên với văn bản này: the fragment returns to the layout from backstack
.
Để xác nhận câu trả lời của tôi, bạn có thể tạo AsyncTask
và gọi SystemClock.sleep(30000)
bên trong số doInbackground
của mình. Bây giờ bạn có thể đẩy mảnh của bạn vào backstack và bật lên từ backstack không có ngoại lệ bởi vì asynctask đã không hoàn thành và khi nó sẽ gọi onPostExecute()
đoạn của bạn đã có một cái nhìn.
Một điều tốt bạn có thể thấy là setRetainInstance
này chỉ có thể được sử dụng với các mảnh vỡ không trong ngăn xếp trở lại.
Vì vậy, khi bạn đẩy mảnh của bạn vào ngăn xếp lại nó thể phá hủy hoàn toàn và bạn có thể được tham khảo đoạn mới khi nó bật lên. Nhưng khi bạn sử dụng setRetainInstance(true);
để thay đổi cấu hình, đoạn của bạn được giữ lại trên Hoạt động tạo lại có nghĩa là cùng một đoạn và onCreate
không được gọi. Và đây là một điều rất quan trọng vì nếu bạn bắt đầu AsyncTask
theo phương pháp onCreate
, khi bạn đẩy đoạn của bạn vào ngăn xếp và bật lên, bạn có thể có đoạn mới và điều này có nghĩa là phương pháp onCreate
và AsyncTask
khác Bị sa thải. Điều đó có nghĩa là bạn không có bất kỳ sự kiểm soát nào đối với số điện thoại gọi AsyncTask
để xem ra cho rò rỉ bộ nhớ!
Sử dụng xe buýt nhắn tin hoặc bộ thu phát nội bộ. – 323go
Đối với thanh tiến trình? : | Đó là một chút nhiều bạn không nghĩ? – JVillella