java - 如何在继续之前等待带有结果回调的方法完成(Android)?

标签 java android

所以我是 Android 的菜鸟,我正在编写一个简单的应用程序,它使用 Google Fit 来存储用户的健身类(class)和步数,然后检索它们。

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

问题是,虽然我首先调用了获取方法,但直到我添加了步骤之后结果才会返回,因此步骤计数始终为零。

这是我的代码:

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<> resultsArrayBlockingQueue<> results .
  2. 调用readAllSessionsgetDaySteps 中的方法方法,调用 while(results.take()!=null) { //rest of the logic }
  3. 你需要某种机制来退出 while当读取所有结果时,在步骤 2 中循环

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

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

public abstract PendingResult readSession (GoogleApiClient client, SessionReadRequest request)

Reads data from the user's Google Fit store of the specific type(s) and for the specific session(s) selected from the request parameters.

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

public abstract R await ()

Blocks until the task is completed. This is not allowed on the UI thread. The returned result object can have an additional failure mode of 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
            }
        }
    }

*results 必须声明为实例/类级变量,以便在类中的所有方法中都可以访问。变量 result 的类型为 PendingResult<SessionReadResults> .另外,看起来你可以取消结果 ArrayList因为你想要的一切都可以从 SessionReadResults 中提取出来由 await 返回方法。最后请注意,此答案尚未使用您的代码进行测试,因为您的代码示例不完整。

关于java - 如何在继续之前等待带有结果回调的方法完成(Android)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29733024/

相关文章:

java - 如何从给定值中查找 Java 中 STRING 数组的索引?

java - 悬停在 JButton 上时出现奇怪的颜色变化

java - 在没有 gradle 的情况下构建和运行 grpc-java 示例

android - 刚刚将我的 OS X 升级到 Yosemite,Android 设备选择器没有显示设备 - 怎么办?

java - 在 Java 中同步线程

java - 如何将依赖项注入(inject)到需要前一个 Activity 参数的 Activity 中?

java - setOnItemLongClickListener 和 setOnItemClickListener 在同一个类上

java - 如何使用 Java POI 从工作簿中删除所有公式

android - Jackson 2 - 在 Android 上使用 Retrofit REST-API 将字符串直接反序列化为 Date

java - 将接口(interface)与其实现分离有什么意义?