Android AsyncQueryHandler上的异常处理

Android AsyncQueryHandler上的异常处理,android,exception-handling,Android,Exception Handling,当使用Android的AsyncQueryHandler时,是否有任何简单的方法来处理异步插入引发的异常,或者我是否需要编写该类的自己版本?查看AsyncQueryHandler源代码,很明显,我可以扩展它以满足我的需要,而不需要太多的痛苦。由于“AsyncQueryHandler异常处理”在google上没有太多内容,所以我在下面附上了我的源代码,以防其他人发现自己也处于同样的情况 基本上,它所做的是扩展AsyncQueryHandler的内部工作线程,并将对该线程的super.handleM

当使用Android的
AsyncQueryHandler
时,是否有任何简单的方法来处理异步插入引发的异常,或者我是否需要编写该类的自己版本?

查看
AsyncQueryHandler
源代码,很明显,我可以扩展它以满足我的需要,而不需要太多的痛苦。由于“AsyncQueryHandler异常处理”在google上没有太多内容,所以我在下面附上了我的源代码,以防其他人发现自己也处于同样的情况

基本上,它所做的是扩展
AsyncQueryHandler
的内部工作线程,并将对该线程的
super.handleMessage
的调用包装在一个try-catch块中,然后将捕获到的异常发送回消息中的主线程,并将其传递到
onError
回调中。默认的
onError
只是重新抛出异常

/**
 * Thin wrapper around @link {@link AsyncQueryHandler} that provides a callback to be invoked 
 * if the asynchronous operation caused an exception.
 */
public class SturdyAsyncQueryHandler extends AsyncQueryHandler {
    public SturdyAsyncQueryHandler(ContentResolver cr) {
        super(cr);
    }

    /**
     * Thin wrapper around {@link AsyncQueryHandler.WorkerHandler} that catches any <code>RuntimeException</code>
     * thrown and passes them back in a reply message. The exception that occurred is
     * in the <code>result</code> field.
     */
    protected class SturdyWorkerHandler extends AsyncQueryHandler.WorkerHandler {
        public SturdyWorkerHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            try {
                super.handleMessage(msg);
            } catch (RuntimeException x) {
                // Pass the exception back to the calling thread (will be in args.result)
                WorkerArgs args = (WorkerArgs) msg.obj;
                Message reply = args.handler.obtainMessage(msg.what);
                args.result = x;
                reply.obj = args;
                reply.arg1 = msg.arg1;
                reply.sendToTarget();
            }
        }
    }

    @Override
    protected Handler createHandler(Looper looper) {
        return new SturdyWorkerHandler(looper);
    }

    /**
     * Called when a runtime exception occurred during the asynchronous operation. 
     * <p>
     * The default re-throws the exception
     * @param token - The token that was passed into the operation
     * @param cookie - The cookie that was passed into the operation
     * @param error - The <code>RuntimeException</code> that was thrown during 
     * the operation
     */
    public void onError(int token, Object cookie, RuntimeException error) {
        throw error;
    }

    @Override
    public void handleMessage(Message msg) {
        if (msg.obj instanceof WorkerArgs) {
            WorkerArgs args = (WorkerArgs) msg.obj;
            if (args.result instanceof RuntimeException) {
                onError(msg.what, args.cookie, (RuntimeException) args.result);
                return;
            }
        }
        super.handleMessage(msg);
    }
}

在插入过程中,我使用hi-lo算法生成主键。如果我的密钥生成器已耗尽其可用密钥的供应,它将抛出一个
OutOfKeysException
。我需要抓住那个例外。类似于
AsyncQueryHandler.onError(Throwable err)
的东西将是理想的选择(这并不存在,但可以告诉你我在追求什么)。@chris你在使用自定义内容提供商吗?@chris所以试着捕捉ContentProvider中的任何错误。insert()@pskink谢谢你的建议,但我真的不想这么做。密钥耗尽将需要一些繁重的错误处理,例如对同步服务器进行“紧急运行”以请求更多密钥(这需要授权,因此用户可能需要输入凭据),如果无法访问服务器等,则通知用户失败。内容提供商似乎不是执行所有这些操作的正确位置。确保您是正确的,当插入ode引发异常时,返回一些“错误”Uri,并将其签入OnInsertComplete非常好用的解决方案。即使几年之后(关于AsyncQueryHandler的文档很少),我也有同样的问题。您的解决方案很有用,但如何捕获AsyncQueryHandler引发的RuntimeException?假设发生错误,我应该在OneError回调中处理它吗?谢谢是的,该类将被子类化,异常处理将在(重写的)OneError回调中发生