如何等待异步方法完成使用Futures?

时间:2015-09-01 14:24:36

标签: android asynchronous retrofit concurrent.futures

我在Android中有一个异步的基于Retrofit的API调用,需要等待DB调用,直到API调用完成,这样我才能确保将正确的数据输入到数据库中。

我读到您可以使用Futures来完成此任务,但是对于我当前的实现,我得到一个空指针异常。

以下是API方法:

public Future<Void> postPrintMode(String authorization, final int userid, String deviceuid, final Map payload){
    api.postPrintMode(authorization, userid, deviceuid, payload, new Callback<PrintMode>() {

        @Override
        public void success(PrintMode printMode, Response response) {

            if (printMode.get_id() != 0) {
                dbOps.writePrintMode(userid, printMode);
                bus.getBus().post(new EVTNewPrintMode(printMode));
            }
        }

        @Override
        public void failure(RetrofitError retrofitError) {
            retrofitError.printStackTrace();
            APIUtils.showAPIResponseBody(retrofitError);
        }
    });

    return null;
}

这里是我想要确保在继续读取数据库结果之前执行异步代码的块。

Future<Void> f = APIExec.getInstance().postPrintMode(IConstants.authorization, IConstants.userId, IConstants.deviceUid, payload);
    // here I get the null pointer exception
    f.get();
    // the code below needs to be executed after the postPrintMode(...) async method;
    DBPrintMode printMode = APIDBOps.getInstance().readPrintModeByPrintModeID(6);
    assertNotNull("Print Mode does not exist", printMode);

2 个答案:

答案 0 :(得分:0)

您可以让调用public Future<Void> postPrintMode方法的类实现new Callback<PrintMode>接口。之后,您可以从中postPrintMode并将引用传递给方法。

这是一个粗略的例子(未经测试的代码)

class Foo implements Callback<PrintMode> {

        Future<Void>  f;

        public Foo(){
            f = APIExec.getInstance().postPrintMode(IConstants.authorization, IConstants.userId, IConstants.deviceUid, this);
        }

        @Override
        public void success(PrintMode printMode, Response response) {

            if (printMode.get_id() != 0) {
                dbOps.writePrintMode(userid, printMode);
                bus.getBus().post(new EVTNewPrintMode(printMode));
            }
            if (f != null){
                f.get();
                // the code below needs to be executed after the postPrintMode(...) async method;
                DBPrintMode printMode = APIDBOps.getInstance().readPrintModeByPrintModeID(6);
                assertNotNull("Print Mode does not exist", printMode);
            }
        }

        @Override
        public void failure(RetrofitError retrofitError) {
            retrofitError.printStackTrace();
            APIUtils.showAPIResponseBody(retrofitError);
        }

}

答案 1 :(得分:0)

创建一个AsyncTaskThread类,如下所示,

public class AsyncTaskThread extends AsyncTask<Void, Void, Void> {

Context context;
Handler myHandler;

public AsyncTaskThread( Context activityContext, Handler handler ) {
    this.context = activityContext;
    this.myHandler = handler;
}

@Override
protected void onPreExecute() {
    // before starting thread you can pre process few things here if needed
}

@Override
protected Void doInBackground(Void... params) {

//在此处执行任何操作,例如调用API并返回结果         return null;     }

@Override
protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    // after doIn Background this method is called which will set the meesage object and give it back to handler
    Message message = new Message();
    message.obj = result;
    myHandler.sendMessage(message);
}

}

将此异步类称为

new AsyncTaskThread(this, new MyHandler()).execute();

并且您必须将此处理程序类放在您放在行上的类中,具体取决于您在句柄中获得的结果,您可以执行进一步的操作,

    private class MyHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
    }
}
相关问题