2012-06-08 23 views
8

Tôi muốn bắt ngoại lệ một chuỗi trong doInBackground và in thông báo lỗi trong onPostExcecute. Vấn đề là tôi không có đối tượng Throwable trong onPostExecute. Làm thế nào để bắt Ngoại lệ trong chủ đề không phải UIin thông báo lỗi trong UI-thread?Bắt ngoại lệ của AsyncTask. Cần suy nghĩ

public class TestTask extends AsyncTask<Void, Void, List<String>> { 

    @Override 
    protected List<String> doInBackground(final Void... params) { 
     try { 
      ... 
      return listOfString; 
     } catch(SomeCustomException e) { 
      ... 
      return null; 
     }  
    } 

    @Override 
    protected void onPostExecute(final List<String> result) { 
     if(result == null) { 
      // print the error of the Throwable "e". 
      // The problem is I don't have the Throwable object here! So I can't check the type of exception. 
     } 

    } 
} 

Cập nhật sau câu trả lời Arun của:

Đây là lớp AsyncTask wrapper của tôi. Nó có ý định xử lý Exception trong doInBackground nhưng tôi không thể tìm ra giải pháp tốt để làm điều đó.

public abstract class AbstractWorkerTask<Params, Progress, Result> 
extends AsyncTask<Params, Progress, Result> 
implements Workable { 
    protected OnPreExecuteListener onPreExecuteListener; 
    protected OnPostExecuteListener<Result> onPostExecuteListener; 
    protected ExceptionHappenedListener exceptionHappendedListener; 
    private boolean working; 

    @Override 
    protected void onPreExecute() { 
     if (onPreExecuteListener != null) { 
      onPreExecuteListener.onPreExecute(); 
     } 
     working = true; 
    } 

    @Override 
    protected void onPostExecute(final Result result) { 
     working = false; 
     if(/* .........*/) { 
      exceptionHappendedListener.exceptionHappended(e); 
     } 
     if (onPostExecuteListener != null) { 
      onPostExecuteListener.onPostExecute(result); 
     } 
    } 

    @Override 
    public boolean isWorking() { 
     return working; 
    } 

    public void setOnPreExecuteListener(final OnPreExecuteListener onPreExecuteListener) { 
     this.onPreExecuteListener = onPreExecuteListener; 
    } 

    public void setOnPostExecuteListener(final OnPostExecuteListener<Result> onPostExecuteListener) { 
     this.onPostExecuteListener = onPostExecuteListener; 
    } 

    public void setExceptionHappendedListener(final ExceptionHappenedListener exceptionHappendedListener) { 
     this.exceptionHappendedListener = exceptionHappendedListener; 
    } 

    public interface OnPreExecuteListener { 
     void onPreExecute(); 
    } 

    public interface OnPostExecuteListener<Result> { 
     void onPostExecute(final Result result); 
    } 

    public interface ExceptionHappenedListener { 
     void exceptionHappended(Exception e); 
    } 
} 
+0

bạn có thể thực hiện một số loại callbacks để thiết lập và nhận được lỗi. –

+0

Tôi đã thử nhưng tôi không thể trả lại cả Ngoại lệ và Danh sách trong doInBackground. Làm thế nào để làm nó? – Emerald214

+0

thử trả về 'e.toString()' thay vì 'null' từ' catch' của 'doInBackground()' ... – GAMA

Trả lời

7

Thay đổi kiểu trả về của doInBackground()-Object và khi bạn nhận được kết quả trong onPostExecute(Object result) sử dụng toán tử instanceOf để kiểm tra nếu kết quả trả về là một Exception hoặc List<String>.

Sửa

Từ kết quả có thể là một ngoại lệ hay khác Danh mục thích hợp, bạn có thể sử dụng như sau:

protected void onPostExecute(final Object result) { 
    working = false; 
    if(result instanceof SomeCustomException) { 
     exceptionHappendedListener.exceptionHappended(result); 
    } 
    else{ 
     if (onPostExecuteListener != null) { 
      onPostExecuteListener.onPostExecute(result); 
     } 
    } 
} 

Cũng thay đổi tuyên bố sau:

public abstract class AbstractWorkerTask<Params, Progress, Object> extends AsyncTask<Params, Progress, Object> 
+0

Điều này hay không giải quyết vấn đề vì bạn không thể thể hiện loại tham số (Danh sách ). : [ – Emerald214

4

Chỉ cần lưu ngoại lệ vào danh sách và xử lý nó sau, vì onPostExecute() luôn được gọi sau doInBackground():

public class TestTask extends AsyncTask<Params, Progress, Result> { 

    List<Exception> exceptions = new ArrayList<Exception>(); 

    @Override 
    protected Result doInBackground(Params... params) { 
    try { 
     ... 
    } catch(SomeCustomException e) { 
     exceptions.add(e); 
    } 
    return result; 
    } 

    @Override 
    protected void onPostExecute(Result result) { 
    for (Exception e : exceptions) { 
     // Do whatever you want for the exception here 
     ... 
    } 
    } 

} 

Đây là doable nhưng hiếm khi được sử dụng, như trong hầu hết các tình huống, chúng tôi muốn xử lý các ngoại lệ ngay sau khi nó được ném và đánh bắt:

public class TestTask extends AsyncTask<Params, Progress, Result> { 

    @Override 
    protected Result doInBackground(Params... params) { 
    try { 
     ... 
    } catch(SomeCustomException e) { 
     // If you need update UI, simply do this: 
     runOnUiThread(new Runnable() { 
     public void run() { 
      // update your UI component here. 
      myTextView.setText("Exception!!!"); 
     } 
     }); 
    } 
    return result; 
    } 

} 

Hy vọng điều này có ý nghĩa.

4

Thay đổi kiểu trả lại là doInBackground thành Object để có thể vượt qua số Exception và sau đó sử dụng instanceof() là nguồn gốc của mã (thực hành lập trình xấu). Nó luôn luôn là thích hợp hơn để hạn chế loại trả lại của bạn đến điều rất cụ thể mà bạn muốn trả về.

Dựa trên điều này answer chỉ cần thêm thành viên riêng tư để lưu ngoại lệ được ném vào doInBackground và sau đó kiểm tra điều đầu tiên trong onPostExecute.

Chỉ cần một số Exception vì bạn nên dừng các hành động trong doInBackground ngay khi ngoại lệ được ném và xử lý nó một cách duyên dáng trong onPostExecute nơi bạn có quyền truy cập vào các yếu tố giao diện người dùng và do đó có thể thông báo cho người dùng về rủi ro.

dụ Generic (cơ thể của AsyncTask):

private Exception mException 

@Override 
protected Result doInBackground(Params... params) { 
    try { 
      // --- Do something --- // 
    } 
    catch(SomeException e){ mException = e; return null; } 
} 

@Override 
protected void onPostExecute(Result result) { 
    if (mException != null) { 
     // --- handle exception --- // 
     return; 
    } 

    // --- Perform normal post execution actions --- // 
} 
Các vấn đề liên quan