2011-11-27 32 views
19

Gần đây tôi đã chuyển đổi Hoạt động của tôi thành Phân đoạn.Các mảnh vỡ được thay thế trong khi AsyncTask được thực hiện - NullPointerException trên getActivity()

Sử dụng điều gì đó tương tự như Điều hướng tab các đoạn được thay thế khi người dùng chọn một tab khác. Sau khi phân đoạn được điền, tôi bắt đầu ít nhất một AsyncTask để nhận một số thông tin từ internet. Tuy nhiên - nếu người dùng chuyển sang tab khác cũng giống như các doBackground-phương pháp từ AsyncTask của tôi đang được thực hiện - đoạn được thay và do đó tôi nhận được một NullPointerException trong dòng đánh dấu:

@Override 
protected Object doInBackground(Object... params) { 
    ... 
    String tempjson = helper.SendPost(getResources().getText(R.string.apiid)); //ERROR: Fragment not attached 
    ... 
} 

protected onPostExecute(Object result) { 
    ... 
    getActivity().getContentResolver() //NULLPOINTEREXCEPTION 
    getView().findViewById(R.id.button) //NULL 
    ... 
} 

getActivity()getResources() gây ra lỗi vì đoạn của tôi bị thay thế.

Những điều tôi đã cố gắng:

  • Calling hủy phương pháp trên AsyncTask tôi (sẽ không sửa lỗi đầu tiên cũng không phải là lỗi thứ hai nếu đoạn được thay thế trong khi onPostExecute() được thực hiện)
  • kiểm tra nếu getActivity()null hoặc gọi this.isDetached() (không phải là một sửa chữa thực tế và tôi cần phải kiểm tra xem nó bất cứ khi nào tôi gọi getActivity() và vân vân)

Vì vậy, câu hỏi của tôi là: những gì sẽ là tốt nhất để thoát khỏi những vấn đề AsyncTask? Tôi không có những vấn đề này khi sử dụng Hoạt động vì chúng không bị "giết"/tách ra khi thay đổi tab (dẫn đến việc sử dụng bộ nhớ cao hơn - lý do tại sao tôi muốn chuyển sang Fragments)

Trả lời

18

AsyncTask đang chạy ở chế độ nền , đoạn của bạn có thể bị tách rời khỏi hoạt động gốc của nó vào thời điểm nó kết thúc. Như bạn đã phát hiện ra, bạn có thể sử dụng isDetached() để kiểm tra. Không có gì sai với điều đó, và bạn không cần phải kiểm tra mọi lúc, chỉ cần xem xét các chu kỳ sống của mảnh và hoạt động.

Hai lựa chọn thay thế khác:

  • Sử dụng Máy bốc hàng, chúng được thiết kế để chơi đẹp hơn với những mảnh
  • Chuyển tải AsyncTask của bạn vào giao diện hoạt động phụ huynh và sử dụng để tách từ các mảnh vỡ. Các hoạt động sẽ biết liệu một mảnh có hay không, và hành động phù hợp (bằng cách loại bỏ kết quả nếu mảnh vỡ đã biến mất).
+8

Bạn nên sử dụng isDetached() chỉ khi bạn tách rời chính mảnh vỡ đó. Khác, bạn nên sử dụng isAdded() để xử lý các trường hợp hệ thống hủy liên kết giữa hoạt động của bạn và đoạn của bạn. – pcans

+0

@Nikolay Elenkov làm thế nào chu kỳ sống có thể tránh kiểm tra mọi lúc trước khi gọi điện thoại hoạt động? – Bear

-1

Bạn đã cố gắng gọi setRetainInstance(true); trong onCreate() chức năng của lớp mảnh của bạn?

+1

Điều này không giúp đỡ trong trường hợp này, các vấn đề là như nhau. Bây giờ tôi đã giải quyết nó bằng cách tạo các trường cho hoạt động và xem và thiết lập chúng trong 'onActivityCreated()' bằng cách sử dụng 'view = getView()' và vân vân. – Boni2k

4

Hôm nay tôi đã phải đối mặt với cùng một vấn đề: khi tôi thay đổi fragment được hiển thị nếu người AsyncTask vẫn chưa kết thúc, và nó cố gắng để truy cập view để cư nó với một số yếu tố nữa, nó sẽ trả về một NullPointerException.

Tôi giải quyết được vấn đề ghi đè một phương pháp trong vòng đời của các đoạn: onDetach(). Phương pháp này được gọi vào thời điểm trước khi fragment được tách ra khỏi activity.

Điều bạn cần làm là gọi phương thức cancel() trên số AsyncTask của mình.Việc này sẽ dừng việc thực hiện tác vụ tránh NullPointerExecption.

Dưới đây là một mẫu của onDetach():

@Override 
public void onDetach() { 
    super.onDetach(); 
    task.cancel(true); 
} 

Kiểm tra trang này để biết thêm thông tin về mảnh vỡ vòng đời: http://developer.android.com/reference/android/app/Fragment.html#Lifecycle Và đây để xem thêm về hủy một nhiệm vụ: http://developer.android.com/reference/android/os/AsyncTask.html

+0

Cảm ơn bạn, cảm ơn bạn rất nhiều. Điều này đã khắc phục được vấn đề của tôi đã khiến tôi lo lắng trong một tuần! –

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