gpt4 book ai didi

android - GMS::LocationClient 中的 DeadObjectException (Android)

转载 作者:太空宇宙 更新时间:2023-11-03 11:57:24 25 4
gpt4 key购买 nike

在 Android 上,我们有一个包装来自 GMS(谷歌移动服务)的 LocationClient 对象的类。 (注意 LocationClient 实现了 com.google.android.gms.common.GooglePlayServicesClient)。

不幸的是,LocationClient 对象有抛出 DeadObjectExceptions 的习惯(例如,当我们调用 locationClient.getLastLocation() 时),我们通过多种日志记录机制检测到这种情况。然而,奇怪的是,LocationClient 没有记录为抛出 DeadObjectExceptions,而且我只能捕获所说的 DeadObjectExceptions ~ 1/40 的时间它们发生 o_0。我们没有针对此问题的重现,我个人也从未见过,但我们的大量用户都会遇到这种情况。

其他说明:

[a] “Caused by: java.lang.IllegalStateException: android.os.DeadObjectException”这一行是关于什么的?这两种异常类型没有祖先-后代关系

[b] 我在 Android 论坛上发帖,但他们当然拒绝了我的帖子,因为“错误的论坛”,而且没有 GMS 论坛,所以我完全不走运。

总而言之,问题是:GMS 正在触发这个奇怪的无法捕获的异常,那么这是怎么回事,我该怎么办?

Here's a stack trace:
com.myapp.android.service.AsyncExecutionException
at com.myapp.android.service.AsyncService$ExceptionThrower.run(MyApp:120)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4794)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.IllegalStateException: android.os.DeadObjectException
at com.google.android.gms.internal.ey.getLastLocation()
at com.google.android.gms.internal.ez.getLastLocation()
at com.google.android.gms.location.LocationClient.getLastLocation()
***at com.myapp.GoogleLocationProvider.getLastLocation(MyApp:92)***
at com.myapp.LocationProducer.getLocation(MyApp:183)
at com.myapp.LocationProducer.getLocationHeader(MyApp:194)
at com.myapp.API.onExecute(MyApp:344)
...
at java.lang.Thread.run(Thread.java:856)
Caused by: android.os.DeadObjectException
at android.os.BinderProxy.transact(Binder.java)
at com.google.android.gms.internal.ex$a$a.a()
at com.google.android.gms.internal.ey.getLastLocation()
at com.google.android.gms.internal.ez.getLastLocation()
***at com.google.android.gms.location.LocationClient.getLastLocation()***
at com.myapp.GoogleLocationProvider.getLastLocation(MyApp:92)
at com.myapp.LocationProducer.getLocation(MyApp:183)
at com.myapp.LocationProducer.getLocationHeader(MyApp:194)
...
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)

------------ 附录------------这是我们的实际代码。您会注意到我们总是事先检查 mLocationClient.isConnected() 是否存在,所以这不是问题所在。有可能我们变得非常不走运,mLocationObject 在调用 isOnConnected() 和 getLastLocation() 之间死掉了,但这对我来说似乎不太可能。我想我可以在通话之前、之间和之后开始记录并找出答案。

LocationClient mLocationClient; // populated somewhere

public Location getLastLocation() {
if (!mLocationClient.isConnected()) {
return null;
}
Location location = null;
try {
location = mLocationClient.getLastLocation();
} catch (Exception e) {
if (!handleDeadObjectException(e)) {
throw e;
}
}
return location;
}

// logs, attempts to handle depending on user configuration
private boolean handleDeadObjectException(Exception e);

最佳答案

来自文档 DeadObjectException :

The object you are calling has died, because its hosting process no longer exists.

意思是,您正试图在另一个不再可用的进程中访问一个对象。例如,如果您绑定(bind)到在不同进程中运行的服务(即 Google 移动服务),则 IBinder您使用的是一个本地对象,它“代表”远程进程中的一个对象。当远程对象不再可用,而您试图使用本地 IBinder 对象时,您将得到 DeadObjectException

所以...

a] what is the line "Caused by: java.lang.IllegalStateException: android.os.DeadObjectException" about? Those two Exceptions types do not have an ancestor-descendant relationship

这两个异常没有任何联系。 IllegalStateException 是实际异常,DeadObjectException 是根异常。

因为 gms.location.LocationClient.getLastLocation() 不想声明公开内部实现的 throw 元素 - 使用 Binder 等 - 它根本就不会。但是当发生诸如 DeadObjectException 之类的异常时,它仍然想抛出,因此它使用运行时异常 IllegalStateException(不需要 throw 声明)。

[b] I posted to the Android forum, but of course they rejected my post as 'wrong forum,' and there's no GMS forum so I'm totally out of luck.

:(

In summary, the question is: GMS is triggering this oddly uncatchable exception, so what's up with that and what can I do?

使用 GMS LocationClient 时,您需要在与客户端交互之前检查 LocationClient.isConnected() 是否存在。请注意,有时 LocationClient.isConnected() 会返回 true 但在调用 LocationClient.getLastLocation() 之后可能仍会抛出 java.lang.IllegalStateException: android.os。 DeadObjectException 其原因是线程问题和竞争条件,当您检查时客户端已连接,但在您实际操作之前连接丢失。

你应该做的是 a) 检查客户端是否已连接

if ( mLocationClient != null && mLocationClient.isConnected() ) {   
mLocationClient.getLastLocation();
}

b) 捕获IllegalStateException(而不是DeadObjectException)

if ( mLocationClient != null && mLocationClient.isConnected() ) {   
try {
mLocationClient.getLastLocation();
} catch (IllegalStateException ex) {
// This will catch the exception, handle as needed
}
}

关于android - GMS::LocationClient 中的 DeadObjectException (Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24288685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com