等到数据从数据库中获取然后返回android

时间:2018-03-21 02:16:37

标签: java android android-asynctask mongodb-query

我正在java中编写一个类,它将从MongoDB数据库中获取结果,然后将结果返回给主程序。我的代码如下:

   public Document[] search(Document query, String databaseName, String collectionName) {
        Log.i(TAG, "Search query: " + query);
    _mongoClient.getDatabase(databaseName).getCollection(collectionName).find(query).continueWith(
            new Continuation<List<Document>, Object>() {

                @Override
                public Object then(@NonNull final Task<List<Document>> task) throws Exception {
                    if (!task.isSuccessful()) {
                        Log.e(TAG, "Failed to execute query");
                    } else {

                        if (task.getResult().size() == 0) {
                            Log.i(TAG, "Query failed to return any results");
                            return null;
                        }


                        results = new Document[task.getResult().size()];
                        for (Integer i = 0; i < task.getResult().size(); i++) {
                            results[i] = task.getResult().get(i);
                            Log.i("test",  results[i].getString("username").toString());
                        }


                    }
                    return null;
                }
            });



    return results;
}

我的代码的问题是它不会等待方法中的代码来检索要运行的数据库。相反,它直接跳转到return语句。 我试过像这样使用AsyncTask:

    private class WaitForDB extends AsyncTask<Void, Void, Void> {

    protected void onPreExecute() {
        super.onPreExecute();

        pd = new ProgressDialog(context);
        pd.setMessage("Please wait");
        pd.setCancelable(false);
        pd.show();
    }

    protected Void doInBackground(Void... params) {
        Document query = new Document("username", "a");
        _mongoClient.getDatabase("gapp").getCollection("parent").find(query).continueWith(
                new Continuation<List<Document>, Object>() {

                    @Override
                    public Object then(@NonNull final Task<List<Document>> task) throws Exception {
                        if (!task.isSuccessful()) {
                            Log.e(TAG, "Failed to execute query");
                        } else {

                            if (task.getResult().size() == 0) {
                                Log.i(TAG, "Query failed to return any results");
                                return null;
                            }


                            results = new Document[task.getResult().size()];
                            for (Integer i = 0; i < task.getResult().size(); i++) {
                                results[i] = task.getResult().get(i);
                                Log.i("test",  results[i].getString("username").toString());
                            }


                        }
                        return null;
                    }
                });
        return null;

    }

    @Override
    protected void onPostExecute(Void result) {

        if (pd.isShowing()) {
            pd.dismiss();
        }

    }

}

然而,这也不起作用。所以,我想知道,有没有办法让程序等到从数据库中检索数据?如果是的话,怎么样?

我会感激任何帮助。 提前致谢。

1 个答案:

答案 0 :(得分:1)

第一个代码不会等待,因为你是这样编写的。如果要观察它,请将更多日志语句放在错误条件之外或构建结果列表的位置,以及返回语句之前。结果列表将在return results之后构建。

您可以做的是将“延续”作为参数传递给方法

public void search(Document query, String databaseName, String collectionName, Continuation<List<Document>, Object> continuation) {
    Log.i(TAG, "Search query: " + query);
    _mongoClient.getDatabase(databaseName)  
         .getCollection(collectionName)
         .find(query)
         .continueWith(continuation);
}   //end method

这就是那种方法。在您需要文件的其他地方进行处理

例如,而不是试图阻止调用结果

Document[] documents = search(...);
// process documents 

你需要调用函数,等待接收结果,然后执行内部回调函数

// Do not define documents here 
search(query, database, collection, 
    new Continuation<List<Document>, Object>() {
        @Override
        public Object then(@NonNull final Task<List<Document>> task) throws Exception {
            if (!task.isSuccessful()) {
                Log.e(TAG, "Failed to execute query");
            } else {
                List<Document> documents = task.getResults();
                // process documents 
            } 
    });
// if you did define documents outside this, it'll still be empty 

如果你想减少所有这些代码只是为了得到一个真正的Document数组,你需要定义自己的接口,但这是没有额外类的最灵活的工作解决方案