Android には、GMS (Google Mobile Services) から LocationClient オブジェクトをラップするクラスがあります。(LocationClient は com.google.android.gms.common.GooglePlayServicesClient を実装することに注意してください)。
残念ながら、LocationClient オブジェクトには DeadObjectExceptions をスローする癖があります (たとえば、locationClient.getLastLocation()を呼び出したとき)。これは、いくつかのログ メカニズムを通じて検出されます。ただし、奇妙なのは、LocationClient が DeadObjectExceptions をスローするように文書化されていないことです。この問題の再現性はなく、個人的に見たことはありませんが、多数のユーザーで発生しています。
その他の注意事項:
[a] 「Caused by: java.lang.IllegalStateException: android.os.DeadObjectException」という行は何ですか? これらの 2 つの例外タイプには、祖先と子孫の関係がありません
[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);