15

Tôi đang sử dụng AsyncTask để thực hiện một số tính toán nền nhưng tôi không thể tìm thấy một cách chính xác để xử lý các ngoại lệ. Hiện nay tôi đang sử dụng đoạn mã sau:Xử lý lỗi Asynctask

private class MyTask extends AsyncTask<String, Void, String> 
{ 
    private int e = 0; 

    @Override 
    protected String doInBackground(String... params) 
    { 
     try 
     { 
      URL url = new URL("http://www.example.com/"); 
     } 
     catch (MalformedURLException e) 
     { 
      e = 1; 
     } 

     // Other code here... 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    { 
     if (e == 1) 
      Log.i("Some Tag", "An error occurred."); 

     // Perform post processing here... 
    } 
} 

Tôi tin rằng e Maye biến được viết/truy cập bởi tất cả các chủ đề chính và lao động. Vì tôi biết rằng onPostExecute() sẽ chỉ chạy sau khi doInBackround() kết thúc, tôi có thể bỏ qua bất kỳ đồng bộ hóa nào không?

Đây có phải là mã không hợp lệ không? Có cách nào được chấp thuận hoặc chính xác để xử lý các ngoại lệ trong một số AsyncTask không?

+1

thể trùng lặp của [AsyncTask và xử lý lỗi trên Android] (http://stackoverflow.com/questions/1739515/asynctask-and-error-handling-on-android) – blahdiblah

Trả lời

3

Tôi đã làm điều đó trong các ứng dụng của mình, tôi đoán không có cách nào tốt hơn.

Bạn cũng có thể đọc Mark Murphy answer về điều đó.

+0

Nếu nó không gây vấn đề sau đó tôi hạnh phúc! – Leo

2

Điều này được đảm bảo hoạt động ngay cả trên kiến ​​trúc SMP. Tất cả việc đồng bộ hóa được thực hiện cho bạn. Tuy nhiên nó sẽ tốt hơn để sử dụng giá trị trả về để làm điều này.

+1

Trong mã thực tế, tôi đang sử dụng một đối tượng tùy chỉnh làm kiểu trả về không thực sự cho vay để giữ thông tin ngoại lệ. Tôi giả sử tôi không thể quá tải chức năng 'onPostExecute()' rất dễ dàng? – Leo

+4

Trước hết, doInBackground phải trả về một đối tượng cùng loại với tham số trong onPostExecute(). Sau đó, bạn chỉ có thể tạo một lớp tùy chỉnh để đóng gói kết quả + ngoại lệ: class ResultHolder {Exception e; MyResult r; } –

2

Tôi nghĩ mã của bạn sẽ thực hiện công việc nhưng đã có một số loại xử lý lỗi được tích hợp vào lớp AsyncTask.

Bạn có thể tránh sử dụng biến số bổ sung bằng cách sử dụng phương thức cancel() và phương thức xử lý của nó onCancelled(). Khi bạn gọi hủy trong phương thức doInBackground(), phương thức onCancelled trong chuỗi giao diện người dùng. Cho dù bạn gọi hủy (true) hoặc hủy (false) phụ thuộc vào nhu cầu của bạn.


private class MyTask extends AsyncTask<String, Void, String> 
{  
    @Override 
    protected NewsItem doInBackground(String... params) 
    { 
     try 
     { 
      URL url = new URL("http://www.example.com/"); 
     } 
     catch (MalformedURLException e) 
     { 
      cancel(false/true); 
     } 

     // Other code here... 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    {    
     // Perform successful post processing here... 
    } 

    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
     // Perform error post processing here... 
    } 
} 
+0

Phương pháp này chỉ hoạt động nếu chúng tôi có một loại ngoại lệ. Trong mã đầy đủ của tôi có nhiều thứ có thể đi sai và chúng phải được xử lý khác nhau. – Leo

+0

Tại sao? Bạn có thể thêm vào mệnh đề try-catch như nhiều thứ mà bạn muốn. Trong mỗi câu lệnh, bạn có thể gọi phương thức hủy. Bạn cũng có thể nắm bắt (Ngoại lệ e) bắt tất cả các loại ngoại lệ. Tôi có đúng không, Leo? Tuy nhiên, có thực tiễn tốt để gọi hủy() khi ngoại lệ được ném hoặc có cách xử lý ngoại lệ khác được triển khai không? – OneWorld

+0

Cách hủy() cách xử lý lỗi rất gần với những gì thực sự xảy ra. Quá trình xử lý của bạn đã bị hủy do lỗi. Bạn vẫn có thể lưu một số trạng thái trên ASyncTask có thể được đọc bởi chuỗi giao diện người dùng để có thêm thông tin về lỗi đó. – DukeMe