繁体   English   中英

如何等待结果回调完成后再继续(Android)?

[英]How to wait for a method with result callback to complete before continuing (Android)?

因此,我是Android的新手,我正在编写一个简单的应用,该应用使用Google Fit来存储用户的健身会话和步数,然后检索它们。

我有两种方法,一种从云中获取给定日期范围内的所有会话,另一种方法遍历这些方法并累加步骤数。

问题是,尽管我首先调用了fetching方法,但直到将步骤加完后结果才返回,因此步骤数始终为零。

这是我的代码:

private ArrayList<> results;

    @Override
    public ArrayList<IndividualSession> readAllSessions(Date dateFrom, Date dateTo) {

    /* I haven't included the following code in this question just to keep things clean, but here there was
        - The initialisation of the results ArrayList
        - Creating the calendar and date objects
        - Building the session read request
    */

    Fitness.SessionsApi.readSession(mGoogleApiClient, readRequest).setResultCallback(new ResultCallback<SessionReadResult>() {
        @Override
        public void onResult(SessionReadResult sessionReadResult) {
            for (Session session : sessionReadResult.getSessions()) {
                List<DataSet> dataSets = sessionReadResult.getDataSet(session);
                for (DataSet dataSet : dataSets) {
                    for (DataPoint dataPoint : dataSet.getDataPoints()) {
                    // Create new IndividualSession object, add data to it then add it to arraylist
                        IndividualSession individualSessionObject = new IndividualSession();
                        individualSessionObject.setFromDate(new Date(session.getStartTime(TimeUnit.SECONDS)));
                        individualSessionObject.setToDate(new Date(session.getEndTime(TimeUnit.SECONDS)));
                        individualSessionObject.setStepCount(dataPoint.getValue(Field.FIELD_STEPS).asInt());
                        results.add(individualSessionObject);
                    }
                }
            }
            Log.i(TAG, "Number of sessions found while reading:  "+results.size());
        }
    });
    return results;
}



@Override
public int getDaySteps(Date dateTo) {
    int stepCount = 0; // to be returned

    // Sort out the dates
    Calendar calFrom = Calendar.getInstance();
    calFrom.add(Calendar.HOUR, -24);

    // Get the sessions for appropriate date range
    ArrayList results =  readAllSessions(calFrom.getTime(), dateTo);
    Log.i(TAG, "Number of sessions found while trying to get total steps: "+results.size());

    // Iterate through sessions to get count steps
    Iterator<IndividualSession> it = results.iterator();
    while(it.hasNext())
    {
        IndividualSession obj = it.next();
        stepCount += obj.getStepCount();
    }
    return stepCount;
}

这个输出

"Number of sessions found while trying to get total steps: 0"
"Number of sessions found while reading:  8"

有两种解决方案:

选项1:使用阻塞性

  1. ArrayList<> results更改为ArrayBlockingQueue<> results
  2. readAllSessions方法中调用getDaySteps方法之后,调用while(results.take()!=null) { //rest of the logic }
  3. 当读取所有结果时,您需要某种机制来退出步骤2中的while循环

选项2:使用PendingResult中的await方法

查看SessionsAPI类的文档,readSessions方法似乎返回PendingResult:

公共抽象PendingResult readSession(GoogleApiClient客户端,SessionReadRequest请求)

从用户的Google Fit存储中读取特定类型的数据,以及从请求参数中选择的特定会话的数据。

查看PendingResult类中await方法的文档:

公共摘要R等待()

阻塞直到任务完成。 UI线程上不允许这样做。 返回的结果对象可以具有INTERRUPTED的其他失败模式。

这就是您可以做的。 而不是将整个调用链接到setResultCallBack,而是首先调用readSessions:

results = Fitness.SessionsApi.readSession(mGoogleApiClient, readRequest);

然后在getDaySteps方法中等待结果:

SessionReadResults sessionResults = results.await();
for (Session session : sessionReadResult.getSessions()) {
        List<DataSet> dataSets = sessionReadResult.getDataSet(session);
        for (DataSet dataSet : dataSets) {
            for (DataPoint dataPoint : dataSet.getDataPoints()) {
            // Create new IndividualSession object, add data to it then add it to arraylist
               IndividualSession individualSessionObject = new IndividualSession();
               individualSessionObject.setFromDate(new Date(session.getStartTime(TimeUnit.SECONDS)));
               individualSessionObject.setToDate(new Date(session.getEndTime(TimeUnit.SECONDS)));
            individualSessionObject.setStepCount(dataPoint.getValue(Field.FIELD_STEPS).asInt());
                    //use the results
            }
        }
    }

*结果必须声明为实例/类级别的变量,才能在该类的所有方法中访问。 变量结果的类型为PendingResult<SessionReadResults> 同样,由于可以从await方法返回的SessionReadResults提取所需的所有内容,因此您可以SessionReadResults结果ArrayList 最后一点,该答案尚未与您的代码一起测试,因为您的代码示例不完整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM