8

doInBackground でスレッドの例外をキャッチし、onPostExcecute でエラー メッセージを出力したいと考えています。問題は、onPostExecute に Throwable オブジェクトがないことです。非 UI スレッドで例外をキャッチし、UI スレッドでエラーメッセージを出力する方法は?

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.
        }

    }
}

Arun の回答後に更新します。

これは私の AsyncTask ラッパー クラスです。doInBackground で例外を処理するつもりですが、それを行うための良い解決策が見つかりません。

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);
    }
}
4

3 に答える 3

7

の戻り値の型を に変更しdoInBackground()Object結果を受け取ったら演算子をonPostExecute(Object result)使用して、返された結果がか かを確認します。instanceOfExceptionList<String>

編集

結果は例外または適切なリストのいずれかになる可能性があるため、次を使用できます。

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

また、次のステートメントを変更します。

public abstract class AbstractWorkerTask<Params, Progress, Object> extends AsyncTask<Params, Progress, Object>
于 2012-06-08T07:18:32.643 に答える
4

onPostExecute() は常に 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
      ...
    }
  }

}

これは実行可能ですが、めったに使用されません。ほとんどの場合、例外がスローされてキャッチされるとすぐに例外を処理する必要があるためです。

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;
  }

}

これが理にかなっていることを願っています。

于 2012-06-08T11:04:39.337 に答える