【问题标题】:Google Fitness: Dealing with TransactionTooLargeException without feedbackGoogle Fitness:在没有反馈的情况下处理 TransactionTooLargeException
【发布时间】:2019-04-23 16:09:10
【问题描述】:

我正在构建一个通过本地(而非 REST)Google Fit API 与 Google Fit 集成的应用程序。我正在使用 Flutter 1.2.1、Kotlin 1.3.21、com.google.android.gms:play-services-fitness:16.0.1 并在带有 Google Play Services 16.0.89 的 Android 8.1.0 上运行该应用程序。

一些 HistoryClient.readData() 请求在没有任何反馈的情况下消失(没有调用 onSuccessListener、onCancelledListener、onFailureListener、onCompleteListener 回调),此时我可以在日志中看到:

   W/Fitness: Error delivering batch 0. Attempt #2
    android.os.TransactionTooLargeException: data parcel size 572360 bytes
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(Binder.java:777)
        at crb.c(:com.google.android.gms@16089017@16.0.89 (040306-239467275):1)
        at yek.a(Unknown Source:8)
        at yta.a(:com.google.android.gms@16089017@16.0.89 (040306-239467275):52)
        at yta.a(:com.google.android.gms@16089017@16.0.89 (040306-239467275):31)
        at ytc.run(:com.google.android.gms@16089017@16.0.89 (040306-239467275):44)
        at rrt.b(:com.google.android.gms@16089017@16.0.89 (040306-239467275):32)
        at rrt.run(:com.google.android.gms@16089017@16.0.89 (040306-239467275):21)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at rxx.run(Unknown Source:7)
        at java.lang.Thread.run(Thread.java:764)

我的理解是本地健身服务(Google Play 服务的一部分)未能发送有关失败的通知,或者我正在使用的 Google Fit 客户端库未能传递它。 这是正确的吗?

其他人如何使用此 API 解决此问题? 为了合理地确定它会在所有手机上成功完成,要求的最佳时间跨度是多少?

注意:我尝试将此作为错误发布在 https://issuetracker.google.com/issues/130402455 上,但没有得到回复,我什至不确定它是否适合。

【问题讨论】:

  • 我猜HistoryClient.readData() 请求的信息太多,这会导致TransactionTooLargeException,您是否可以随意拆分信息?
  • @jackz314 当然可以,但是我需要将它拆分到什么程度呢?我想要一个月的数据和一天的部分似乎是合理的,但有时会发生这种异常。也许它似乎可以在我的手机上使用半天增量,但是速度较慢的手机或具有更多数据的帐户呢?
  • 通常,如果数据大于 200k,则会抛出 TransactionTooLargeException 错误,所以我会说您现在请求的数据不到一半
  • 我想到了一种捕获错误日志的方法,这是一种 hack,但它可能是目前唯一可行的方法,它应该可以工作,请查看我的答案。

标签: android google-fit google-fit-sdk


【解决方案1】:

TransactionTooLargeException 表示任何类型的服务/应用程序之间的数据交换超过了Android允许的数据上限。通常,大小限制在 200KB 左右,但可能会有所不同(我也不是 100% 确定)。

解决方案是拆分您请求的数据,查看 Google Fit API,我认为您可以通过在DataRequest 中设置更短的时间范围来尝试一次获取更少的数据。在您的情况下,错误提示您请求大约 500KB 的数据,这意味着您可以尝试将请求的时间跨度缩短到一半左右。

但即便如此,实际数据大小也可能会因用户的活动而有很大差异,并且多次请求太少并不理想,因此我认为您可以尝试在请求后设置计时器,如果过了一段时间没有返回数据,请减少请求的时间跨度并重试(因为无法捕获错误)。

捕获错误的另一种方法是在单独的线程中读取日志,如果它捕获到TransactionTooLargeException,它将回调并通知您减少请求的时间跨度。您可以像这样捕获日志:

try {
  Process process = Runtime.getRuntime().exec("logcat *:S Fitness:W");//only show Google Fitness related logs
  BufferedReader bufferedReader = new BufferedReader(
  new InputStreamReader(process.getInputStream()));
  String line = "";
  while ((line = bufferedReader.readLine()) != null) {
     if(line.contains("Error delivering batch")){
        //do your callback here
     }
  }
  } 
catch (IOException e) {}

如果没有抛出异常,我会说这是 Google 的一个错误,因为他们没有考虑这种情况并捕获该异常,这将是一个有效的错误报告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多