I am writing an app which just constantly marks your location and orientation using google maps API v2. The app works so far in the so much as the marker changes with your location and orientation, but after appoximately 20 minutes, the app crashes with a "JNI ERROR (app bug): global reference table overflow (max=51200) message." In the code, I basically register a location listener for GPS locations and an accelerometer and magnetic field listener for orientation. On location updates, I store the current location in a private field. On sensor, updates, I store the rotation in a private field and update the position of my google maps marker. I've pasted the relevant code below
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
// Set up GPS and sensors
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build(););
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
}
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
if (mGoogleApiClient.isConnected())
startLocationUpdates();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
mSensorManager.unregisterListener(this);
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
public void onConnected(Bundle bundle) {
// Get the last known location and update map view to that location
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mMarker == null) {
mMarker = createMarker(mCurrentLocation, mMarker, mRotation, R.drawable.arrow);
} else {
setMarkerToLocation(mCurrentLocation, mMarker, mRotation);
}
// Set up location updates
mLocationRequest = new LocationRequest();
// Set interval to be 1 second
mLocationRequest.setInterval(1000)
// Set fastest interval to be 1 second
.setFastestInterval(1000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
startLocationUpdates();
}
private Marker createMarker(Location location, Marker marker,
float rotation, int drawableId) {
if (mMap != null) {
if (location != null) {
marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(location.getLatitude(),
location.getLongitude()))
.anchor(0.5f, 0.5f) //Set anchor to middle of marker
.rotation(rotation)
.icon(BitmapDescriptorFactory.fromResource(drawableId)));
}
}
return marker;
}
private void setMarkerToLocation(Location location, Marker marker,
float rotation) {
if (mMap != null && location != null) {
marker.setPosition(new LatLng(location.getLatitude(),
location.getLongitude()));
marker.setRotation(rotation);
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity = lowpass(event.values, mGravity);
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic = lowpass(event.values, mGeomagnetic);
}
if (mGravity != null && mGeomagnetic != null) {
float RotMatrix[] = new float[9];
float IncMatrix[] = new float[9];
if (SensorManager.getRotationMatrix(RotMatrix, IncMatrix, mGravity, mGeomagnetic)) {
float orientation[] = new float[3];
SensorManager.getOrientation(RotMatrix, orientation);
mRotation = (float) Math.toDegrees(orientation[0]);
if (mMarker == null) {
mMarker = createMarker(mCurrentLocation, mMarker, mRotation, R.drawable.arrow);
} else {
setMarkerToLocation(mCurrentLocation, mMarker, mRotation);
}
}
}
}
Here is a snippet from my logcat output:
A/art﹕ art/runtime/indirect_reference_table.cc:98] JNI ERROR (app bug): global reference table overflow (max=51200)
A/art﹕ art/runtime/indirect_reference_table.cc:98] global reference table dump:
A/art﹕ art/runtime/indirect_reference_table.cc:98] Last 10 entries (of 51200):
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51199: 0x17b68580 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51198: 0x17b68520 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51197: 0x17b684c0 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51196: 0x17b68460 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51195: 0x17b68380 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51194: 0x17b68320 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51193: 0x17b682c0 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51192: 0x17b68260 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51191: 0x17b68200 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 51190: 0x17b681a0 com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] Summary:
A/art﹕ art/runtime/indirect_reference_table.cc:98] 971 of com.google.android.gms.clearcut.a.h (971 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.view.ViewRootImpl$AccessibilityInteractionConnection
A/art﹕ art/runtime/indirect_reference_table.cc:98] 2322 of com.google.android.gms.clearcut.a.h (2322 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
A/art﹕ art/runtime/indirect_reference_table.cc:98] 2057 of com.google.android.gms.clearcut.a.h (2057 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of dalvik.system.VMRuntime
A/art﹕ art/runtime/indirect_reference_table.cc:98] 141 of com.google.android.gms.clearcut.a.h (141 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.hardware.SystemSensorManager$SensorEventQueue
A/art﹕ art/runtime/indirect_reference_table.cc:98] 7212 of com.google.android.gms.clearcut.a.h (7212 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 2 of android.app.LoadedApk$ServiceDispatcher$InnerConnection (2 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 3145 of com.google.android.gms.clearcut.a.h (3145 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.opengl.EGLDisplay
A/art﹕ art/runtime/indirect_reference_table.cc:98] 4 of com.google.android.gms.clearcut.a.h (4 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.opengl.EGLDisplay
A/art﹕ art/runtime/indirect_reference_table.cc:98] 279 of com.google.android.gms.clearcut.a.h (279 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of float[] (16 elements)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1812 of com.google.android.gms.clearcut.a.h (1812 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.view.ViewRootImpl$W
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1610 of com.google.android.gms.clearcut.a.h (1610 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of java.lang.ref.WeakReference
A/art﹕ art/runtime/indirect_reference_table.cc:98] 4 of com.google.android.gms.clearcut.a.h (4 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 5 of java.lang.ref.WeakReference (5 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 5 of java.lang.ref.WeakReference (5 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 10 of java.lang.ref.WeakReference (10 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 3 of java.lang.ref.WeakReference (3 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 467 of com.google.android.gms.clearcut.a.h (467 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.view.WindowManagerGlobal$1
A/art﹕ art/runtime/indirect_reference_table.cc:98] 3925 of com.google.android.gms.clearcut.a.h (3925 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.opengl.EGLSurface
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of com.google.android.gms.clearcut.a.h
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of android.opengl.EGLSurface
A/art﹕ art/runtime/indirect_reference_table.cc:98] 624 of com.google.android.gms.clearcut.a.h (624 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of java.lang.Class
A/art﹕ art/runtime/indirect_reference_table.cc:98] 274 of com.google.android.gms.clearcut.a.h (274 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 15 of java.lang.Class (13 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 18 of com.google.android.gms.clearcut.a.h (18 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 5 of java.lang.Class (1 unique instances)
A/art﹕ art/runtime/indirect_reference_table.cc:98] 1 of com.google.android.gms.clearcut.a.h