我从主Activity
的Gps定位元素在与UI线程不同的线程上运行:
public class MyActivity extends Activity {
...
public Handler gpshandler = null;
public void onCreate(Bundle savedInstanceState) {
...
Thread gpsThread = new Thread(new Runnable() {
public void run() {
Looper.prepare();
gpshandler = new Handler();
gps = new GPSClass(MyActivity.this);
Looper.loop();
}
}, "GPSThread");
gpsThread.start();
}
...
@Override
protected void onDestroy() {
super.onDestroy();
gps.onPause();
gpshandler.getLooper().quit();
}
我的GPSClass如下:
public class GPSClass implements LocationListener, GpsStatus.Listener{
private double latitute, longitude;
private LocationManager locationManager;
private String provider;
private GpsStatus status;
private boolean hasGPSFix = false;
private Location lastLoc;
private long lastLocTime;
private boolean started = false;
public GPSClass(Context context) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationManager.addGpsStatusListener(this);
start();
started = true;
}
private void start() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setCostAllowed(false);
criteria.setSpeedRequired(false);
criteria.setAltitudeRequired(false);
if(hasGPSFix || !started) {
provider = locationManager.getBestProvider(criteria, true);
} else {
provider = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) ?
LocationManager.NETWORK_PROVIDER : locationManager.getBestProvider(criteria, true);
}
if(provider != null){
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
onLocationChanged(location);
} else {
latitute = 0.0;
longitude = 0.0;
}
}
computeLocation();
}
public void computeLocation(){
locationManager.requestLocationUpdates(provider, 20000, 100, this);
}
public void onPause(){
locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
lastLocTime = SystemClock.elapsedRealtime();
latitute = location.getLatitude();
longitude = location.getLongitude();
lastLoc = location;
}
@Override
public void onProviderDisabled(String provider) {
start();
}
@Override
public void onProviderEnabled(String provider) {
start();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) { // not a good method, there are some issues with it not being called, don't rely on it!
if(status != LocationProvider.TEMPORARILY_UNAVAILABLE){
start();
}
}
public double getLatitute() {
return latitute;
}
public double getLongitude() {
return longitude;
}
public String getProvider() {
return provider;
}
@Override
public void onGpsStatusChanged(int event) {
status = locationManager.getGpsStatus(status);
switch (event) {
case GpsStatus.GPS_EVENT_STARTED:
// Do Something
break;
case GpsStatus.GPS_EVENT_STOPPED:
// Do Something
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
hasGPSFix = true;
// Do Something
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
if (lastLoc != null)
hasGPSFix = (SystemClock.elapsedRealtime() - lastLocTime) < 10000;
if (hasGPSFix) {
// Do something.
} else {
start();
}
// Do Something
break;
}
}
}
我使用gpshandler执行Looper.quit()方法,并使用我的gps对象的get方法获取位置。
这种方法工作正常,我可以获取所需的信息。但是,有时(一半时间)我会收到以下警告消息:
Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {41ada040} sending message to a Handler on a dead thread
java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {41ada040} sending message to a Handler on a dead thread
at android.os.Handler.sendMessageAtTime(Handler.java:473)
at android.os.Handler.sendMessageDelayed(Handler.java:446)
at android.os.Handler.sendMessage(Handler.java:383)
at android.location.LocationManager$GpsStatusListenerTransport.onGpsStopped(LocationManager.java:1382)
at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:57)
at dalvik.system.NativeStart.run(Native Method)
要么
Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {41ada040} sending message to a Handler on a dead thread
java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {41ada040} sending message to a Handler on a dead thread
at android.os.Handler.sendMessageAtTime(Handler.java:473)
at android.os.Handler.sendMessageDelayed(Handler.java:446)
at android.os.Handler.sendMessage(Handler.java:383)
at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1382)
at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:57)
at dalvik.system.NativeStart.run(Native Method)
这些警告不会影响流程,但我想了解发生了什么...
使用DDMS,我发现这些警告发生在Binder线程上。有谁知道为什么发生这种情况,为什么一直没有发生呢?谢谢
编辑
我已经研究了一下,我意识到当它们发生时,它们可以出现在所有的绑定器上,但是它们一次只影响其中的两个。我对Binders并不熟悉,但是是否可以广播有关状态的信息?我不知道如何将Binders附加到哪些线程上,并且已经尝试了调试,但是由于某种原因,我无法在调试模式下重现警告。但是,我在onGpsStatusChanged方法中设置了一个调试日志,该报告报告了收到的gps状态。这是logcat的输出。我刚刚对其进行了编辑,以显示消息出现在哪些线程上。
12-12 09:32:18.133: W/MessageQueue(Binder_3): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:18.133: W/MessageQueue(Binder_3): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:18.133: W/MessageQueue(Binder_3): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:18.133: D/gps(GPSThread): got status 4
12-12 09:32:18.133: W/MessageQueue(Binder_1): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:18.133: W/MessageQueue(Binder_1): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:18.133: W/MessageQueue(Binder_1): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:19.128: W/MessageQueue(Binder_1): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:19.128: W/MessageQueue(Binder_1): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:19.128: W/MessageQueue(Binder_1): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:19.128: D/gps(GPSThread): got status 4
12-12 09:32:19.128: W/MessageQueue(Binder_5): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:19.128: W/MessageQueue(Binder_5): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:19.128: W/MessageQueue(Binder_5): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:20.123: W/MessageQueue(Binder_3): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:20.123: W/MessageQueue(Binder_3): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:20.123: W/MessageQueue(Binder_3): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:20.123: D/gps(GPSThread): got status 4
12-12 09:32:20.123: W/MessageQueue(Binder_4): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:20.123: W/MessageQueue(Binder_4): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:20.123: W/MessageQueue(Binder_4): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:21.173: D/gps(GPSThread): got status 4
12-12 09:32:21.173: W/MessageQueue(Binder_2): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:21.173: W/MessageQueue(Binder_2): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:21.173: W/MessageQueue(Binder_2): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:21.178: W/MessageQueue(Binder_3): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:21.178: W/MessageQueue(Binder_3): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:21.178: W/MessageQueue(Binder_3): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:22.108: D/gps(GPSThread): got status 4
12-12 09:32:22.113: W/MessageQueue(Binder_5): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:22.113: W/MessageQueue(Binder_5): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {425536f8} sending message to a Handler on a dead thread
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:22.113: W/MessageQueue(Binder_5): at dalvik.system.NativeStart.run(Native Method)
12-12 09:32:22.113: W/MessageQueue(Binder_3): Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:22.113: W/MessageQueue(Binder_3): java.lang.RuntimeException: Handler (android.location.LocationManager$GpsStatusListenerTransport$1) {42602058} sending message to a Handler on a dead thread
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageAtTime(Handler.java:473)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.os.Handler.sendMessageDelayed(Handler.java:446)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.os.Handler.sendMessage(Handler.java:383)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.location.LocationManager$GpsStatusListenerTransport.onSvStatusChanged(LocationManager.java:1406)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.location.IGpsStatusListener$Stub.onTransact(IGpsStatusListener.java:89)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at android.os.Binder.execTransact(Binder.java:367)
12-12 09:32:22.113: W/MessageQueue(Binder_3): at dalvik.system.NativeStart.run(Native Method)
最佳答案
我不完全了解实际发生的情况,但是我有一个模糊的想法...在添加Looper.loop()
之前以及完全初始化我的GPSClass之前,我正在添加GPS侦听器。
因此,我猜测LocationProvider
所使用的LocationManager
有时会因为我的侦听器类尚未完成初始化或循环程序尚未启动而崩溃。
但是,仍然添加了侦听器,这可以解释为什么我仍在获取更新。我仍然不明白为什么我在不同的Binders
上收到警告...
我发现的解决方案是通过活动的LocationManager
而不是onResume()
触发的方法将Gps侦听器添加到onCreate
,并在GPSClass执行.removeGpsStatusListener()
时执行onPause()
。
非常感谢您zapl的投入;)