DeadObjectException in GMS::LocationClient (Android)

后端 未结 1 815
情歌与酒
情歌与酒 2021-01-06 19:46

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.GooglePla

1条回答
  •  有刺的猬
    2021-01-06 20:22

    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
        }
    }
    

    0 讨论(0)
提交回复
热议问题