DeadObjectException大湄公河次区域:: LocationClient(安卓) [英] DeadObjectException in GMS::LocationClient (Android)

查看:265
本文介绍了DeadObjectException大湄公河次区域:: LocationClient(安卓)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

不幸的是,LocationClient对象抛出DeadObjectExceptions的习惯(例如,当我们调用的 locationClient.getLastLocation()),这是我们通过我们的一些记录机制检测。有什么奇怪的,但问题在于,LocationClient未记录抛DeadObjectExceptions,此外我只能够赶上称,发生O_0时间DeadObjectExceptions〜1/40。我们没有摄制对于这个问题,我个人从来没有见过它,但它发生了大量的使用者。

其他注意事项:

[一]什么是线产生的原因:java.lang.IllegalStateException:android.os.DeadObjectException呢?这两个例外类型没有一个祖先,后裔关系

[b]我贴到了Android论坛,但当然,他们拒绝了我的职务是错误的论坛,并没有大湄公河次区域论坛,所以我完全不走运。

总之,问题是:大湄公河次区域是触发这一奇怪的是不可捕获的异常,所以什么是与这一点,我该怎么办

 这里有一个堆栈跟踪:
com.myapp.android.service.AsyncExecutionException
     在com.myapp.android.service.AsyncService $ ExceptionThrower.run(MyApp的:120)
     在android.os.Handler.handleCallback(Handler.java:615)
     在android.os.Handler.dispatchMessage(Handler.java:92)
     在android.os.Looper.loop(Looper.java:137)
     在android.app.ActivityThread.main(ActivityThread.java:4794)
     在java.lang.reflect.Method.invokeNative(Method.java)
     在java.lang.reflect.Method.invoke(Method.java:511)
     在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:789)
     在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
     在dalvik.system.NativeStart.main(NativeStart.java)
致:java.lang.IllegalStateException:android.os.DeadObjectException
     在com.google.android.gms.internal.ey.getLastLocation()
     在com.google.android.gms.internal.ez.getLastLocation()
     在com.google.android.gms.location.LocationClient.getLastLocation()
     ***在com.myapp.GoogleLocationProvider.getLastLocation(MyApp的:92)***
     在com.myapp.LocationProducer.getLocation(MyApp的:183)
     在com.myapp.LocationProducer.getLocationHeader(MyApp的:194)
     在com.myapp.API.onExecute(MyApp的:344)
     ...
     在java.lang.Thread.run(Thread.java:856)
android.os.DeadObjectException:产生的原因
     在android.os.BinderProxy.transact(Binder.java)
     在com.google.android.gms.internal.ex $ A $ A.A()
     在com.google.android.gms.internal.ey.getLastLocation()
     在com.google.android.gms.internal.ez.getLastLocation()
     ***在com.google.android.gms.location.LocationClient.getLastLocation()***
     在com.myapp.GoogleLocationProvider.getLastLocation(MyApp的:92)
     在com.myapp.LocationProducer.getLocation(MyApp的:183)
     在com.myapp.LocationProducer.getLocationHeader(MyApp的:194)
     ...
     在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
     在java.util.concurrent.FutureTask.run(FutureTask.java:137)
     在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
     在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
     在java.lang.Thread.run(Thread.java:856)
 

------------附录------------- 这里是我们的实际code。你会发现,我们总是检查是否mLocationClient.isConnected()事前,所以这不是问题。这是可能的,我们正在变得非常不吉利的,并调用isOnConnected()和getLastLocation()之间mLocationObject去世,但似乎不可能给我。我想我可以开始先登录,之间,以及呼叫后找出来。

  LocationClient mLocationClient; //居住的地方

公共场所getLastLocation(){
    如果(!mLocationClient.isConnected()){
        返回null;
    }
    位置位置= NULL;
    尝试 {
        位置= mLocationClient.getLastLocation();
    }赶上(例外五){
        如果(!handleDeadObjectException(E)){
            扔ê;
        }
    }
    返回的位置;
}

//日志,尝试处理取决于用户配置
私人布尔handleDeadObjectException(例外五);
 

解决方案

从文档<一href="http://developer.android.com/reference/android/os/DeadObjectException.html">DeadObjectException:

  

您呼叫的对象已经死了,因为它的宿主进程不再存在。

这意味着,你要访问在不同的进程不可用了一个对象。例如,如果你绑定到运行在不同的进程(例如谷歌手机业务)的的IBinder <服务/ A>你用的是本地对象,重新presents远程进程中的对象。当远程对象不再可用,并且您尝试使用当地的IBinder对象,你会得到的 DeadObjectException

所以...

  

一]什么是线产生的原因:java.lang.IllegalStateException:android.os.DeadObjectException呢?这两个例外类型没有一个祖先,后裔关系

这两个异常不以任何方式连接。在 IllegalStateException异常是实际的异常和 DeadObjectException 是根例外。

由于 gms.location.LocationClient.getLastLocation()的并不想声明,揭露内部实现掷元素 - 用粘合剂和这样的工作 - 它根本就没有。但是,当一个例外,如 DeadObjectException 情况仍然要抛,所以它采用了运行时异常 IllegalStateException异常(它不需要扔声明)。

  

[b]我贴到了Android论坛,但当然,他们拒绝了我的职务是错误的论坛,并没有大湄公河次区域论坛,所以我完全不走运。

  

总之,问题是:大湄公河次区域是触发这一奇怪的是不可捕获的异常,所以什么是与这一点,我该怎么办

在与LocationClient您需要检查的大湄公河次区域合作,如果 LocationClient.isConnected()与客户交互之前。注意,有时 LocationClient.isConnected()将返回true,但下面的调用为 LocationClient.getLastLocation()可能仍然抛出的 java.lang.IllegalStateException:android.os。 DeadObjectException 并针对原因就是线程问题,并在客户端当您检查连接但连接有你的实际行动之前丢失。比赛条件

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

 如果(mLocationClient = NULL和放大器;!&安培; mLocationClient.isConnected()){
    mLocationClient.getLastLocation();
}
 

二)抓住 IllegalStateException异常(而不是 DeadObjectException

 如果(mLocationClient = NULL和放大器;!&安培; mLocationClient.isConnected()){
    尝试 {
        mLocationClient.getLastLocation();
    }赶上(IllegalStateException异常前){
        //这将捕捉异常,柄根据需要
    }
}
 

On Android we have a class that wraps a LocationClient object from GMS (Google Mobile Services). (Note that LocationClient implements com.google.android.gms.common.GooglePlayServicesClient).

Unfortunately the LocationClient object has a habit of throwing DeadObjectExceptions (e.g. when we invoke locationClient.getLastLocation()), which we detect through several of our logging mechanisms. What's weird, however, is that LocationClient isn't documented as throwing DeadObjectExceptions, and furthermore I'm only able to catch said DeadObjectExceptions ~ 1/40th of the time they occur o_0. We have no repro for this issue and I've personally never seen it, however it occurs for a large number of our users.

Other notes:

[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

[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?

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)

------------ ADDENDUM ------------- Here is our actual code. You'll notice we always check whether mLocationClient.isConnected() beforehand, so that's not the issue. It's possible we're getting extremely unlucky and mLocationObject dies between invoking isOnConnected() and getLastLocation(), however that seems improbable to me. I suppose I can start to log before, between, and after the calls and find out.

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);

解决方案

From the documentation DeadObjectException:

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

Meaning, you are trying to reach an object in a different process that is not available anymore. For example, if you bind to a service that runs in a different process (i.e. Google Mobile Services) the IBinder you use is a local object that "represents" an object in the remote process. When the remote object is not available any more, and you are trying to use the local IBinder object, you will get the DeadObjectException.

So...

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

The two exceptions are not connected in any way. The IllegalStateException is the actual exception and the DeadObjectException is the root exception.

Since gms.location.LocationClient.getLastLocation() does not want to declare throw elements that expose inner implementations - working with binders and such - it simply don't. But when an exception such as DeadObjectException happens it still wants to throw and so it uses a runtime exception IllegalStateException (which doesn't need throw declaration).

[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?

When working with the GMS LocationClient you need to check if LocationClient.isConnected() before interacting with the client. Note that sometimes LocationClient.isConnected() will return true but following invocation to LocationClient.getLastLocation() might still throw java.lang.IllegalStateException: android.os.DeadObjectException and the reason for that is threading issues and race conditions where the client was connected when you checked but then connection got lost before your actual action.

What you should do is a) Check if client is connected

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

b) Catch the IllegalStateException (and not the DeadObjectException)

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

这篇关于DeadObjectException大湄公河次区域:: LocationClient(安卓)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆