2012-06-23 30 views
6

SDK Android v15 chạy trên thiết bị 2.3.6.AsyncTask.onCancelled() không được gọi sau khi hủy (đúng)

Tôi gặp sự cố trong đó onPostExecute() vẫn đang được gọi khi tôi gọi cancel() trong một cuộc gọi doInBackground().

Đây là mã của tôi:

@Override 
public String doInBackground(String... params) { 
    try { 
     return someMethod(); 
    } catch (Exception e) { 
     cancel(true); 
    } 

    return null; 
} 

public String someMethod() throws Exception { 
    ... 
} 

Tôi buộc someMethod() để ném một ngoại lệ để kiểm tra này ra, và thay vì onCancelled được gọi, tôi luôn luôn quay trở lại onPostExecute(). Nếu tôi kiểm tra isCancelled() giá trị trả về là đúng, vì vậy tôi biết rằng cancel(true) đang được thực thi.

Bất kỳ ý tưởng nào?

Trả lời

6

onCancelled chỉ được hỗ trợ từ cấp API Android 11 (Honeycomb 3.0.x). Điều này có nghĩa là, trên một thiết bị Android 2.3.6, nó sẽ không được gọi.

Tốt nhất là để có điều này trong onPostExecute:

protected void onPostExecute(...) { 
    if (isCancelled() && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
     onCancelled(); 
    } else { 
     // Your normal onPostExecute code 
    } 
} 

Nếu bạn muốn tránh việc kiểm tra phiên bản, bạn thay vì có thể làm:

protected void onPostExecute(...) { 
    if (isCancelled()) { 
     customCancelMethod(); 
    } else { 
     // Your normal onPostExecute code 
    } 
} 
protected void onCancelled() { 
    customCancelMethod(); 
} 
protected void customCancelMethod() { 
    // Your cancel code 
} 

Hy vọng rằng sẽ giúp! :)

+1

chúng không được gọi là ... – Radu

+0

@Radu Tôi không biết mã bạn đang sử dụng hoặc tác vụ bạn đang cố thực hiện. Bạn có thể là tốt nhất để bắt đầu một câu hỏi mới nếu bạn đã cố gắng để làm một cái gì đó tương tự như thế này và đang nhận được vấn đề. – Eric

+0

quan điểm của tôi là tôi không thể @ ghi đè lên kết quả onCancelled (SomeType) và onCancelled() đơn giản. Ngoài ra, nếu tôi đang nhắm mục tiêu phiên bản Android cũ, onCancelled() sẽ không được gọi ... – Radu

21

Theo tài liệu API Android, onCancelled() là có kể từ mức API 3, trong khi onCancelled(Object result) đã được thêm vào chỉ từ mức API 11. Do đó, nếu mức nền tảng API là dưới 11, onCancelled() sẽ được gọi luôn luôn trong khi onCancelled(Object) sẽ được gọi luôn luôn nếu không.

Vì vậy, nếu bạn muốn chạy mã của mình trên tất cả các API cấp 3 trở lên, bạn cần triển khai cả hai phương pháp. Để có hành vi tương tự bạn có thể muốn để lưu trữ kết quả trong một biến Ví dụ để isCancelled() thể được sử dụng như hình dưới đây:

public class MyTask extends AsyncTask<String, String, Boolean> { 
    private Boolean result; 
    // . . . 
    @Override 
    protected void onCancelled() { 
    handleOnCancelled(this.result); 
    } 
    @Override 
    protected void onCancelled(Boolean result) { 
    handleOnCancelled(result); 
    } 
    //Both the functions will call this function 
    private void handleOnCancelled(Boolean result) { 
    // actual code here 
    } 
} 

Bằng cách này, mã của Eric làm việc không có khả năng bởi vì doc API Android nói:

gọi phương thức cancel() sẽ dẫn đến onCancelled(Object) được gọi trên thread UI sau doInBackground(Object[]) lợi nhuận. Gọi phương thức cancel() đảm bảo rằng onPostExecute(Object) không bao giờ được gọi.

+0

Nó làm cho ngày của tôi. –

+1

Câu trả lời hay nhưng tên phương thức tồn tại lỗi chính tả. Tôi đoán nó nên được "handleOnCancelled". – TonyQ

+1

Gọi phương thức cancel() đảm bảo rằng onPostExecute (Object) không bao giờ được gọi, điều đó chỉ phù hợp với tổ ong và sau đó cho các phiên bản trước đó tham chiếu đến câu trả lời @eric –

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